Data.Binary, Data.Text and errors

Hi all, I have noticed that in both Data.Binary and Data.Text (which is still experimental, but still), the "decode" functions can be undefined (i.e. bottom) if they encounter malformed input. What is the preferred way to use these functions in a safe way? For example, if one writes data to a disk using Data.Binary and wants to read it back in at a later date, how can one ensure that it is valid so that Data.Binary does not hit an error? Or do you just have to catch the exception in the IO Monad? Alex

On Sun, Mar 15, 2009 at 8:40 PM, Alexander Dunlap < alexander.dunlap@gmail.com> wrote:
I have noticed that in both Data.Binary and Data.Text (which is still experimental, but still), the "decode" functions can be undefined (i.e. bottom) if they encounter malformed input.
For decoding Unicode, it's typical to provide a flexible API that can do one of the following on a bad encoding: - Substitute a character - Skip it - Return the partial decode - Throw an exception I just haven't gotten there yet.

On Sun, Mar 15, 2009 at 9:13 PM, Bryan O'Sullivan
On Sun, Mar 15, 2009 at 8:40 PM, Alexander Dunlap
wrote: I have noticed that in both Data.Binary and Data.Text (which is still experimental, but still), the "decode" functions can be undefined (i.e. bottom) if they encounter malformed input.
For decoding Unicode, it's typical to provide a flexible API that can do one of the following on a bad encoding:
Substitute a character Skip it Return the partial decode Throw an exception
I just haven't gotten there yet.
Thanks! I guess we'll see how this comes together. Does anyone know about error handling options in Data.Binary? Are there plans to add an error handling mechanism? Alex

On Monday 16 March 2009 06:40:12 Alexander Dunlap wrote:
Hi all,
I have noticed that in both Data.Binary and Data.Text (which is still experimental, but still), the "decode" functions can be undefined (i.e. bottom) if they encounter malformed input.
What is the preferred way to use these functions in a safe way? For example, if one writes data to a disk using Data.Binary and wants to read it back in at a later date, how can one ensure that it is valid so that Data.Binary does not hit an error? Or do you just have to catch the exception in the IO Monad?
I've used ErrorT monad transformer for decoding. With that it's possible to work around this problem. As downside one is required to do all checks and throw errors manually. It would be nice to have some kind of error handling in Data.Binary How it was done:
import Control.Monad.Error
-- | Get monad with applied to it Error monad transformer type Decoder = ErrorT String Get
-- | Subequipment data data SubEq = SubEq { subeqID :: Int , subeqData :: ByteString }
-- | Abort execution if function evaluates to True dieIf :: (a -> Bool) -> String -> a -> Decoder () dieIf f err x = when (f x) (throwError err)
readSubEq :: Decoder SubEq readSubEq = do lift remaining >>= dieIf (<4) "DATE: Too short subequipment data (<4)" -- Read header len <- liftM (\x -> fromIntegral $ 2*x - 4) $ lift getWord16le s_id <- liftM fromIntegral $ lift getWord16le lift remaining >>= dieIf (< len) "DATE: Too short subequipment data" buf <- lift $ getLazyByteString len return $! SubEq s_id buf
-- Actual decoding decodeSubEq = runGet (runErrorT readSubEq)
participants (3)
-
Alexander Dunlap
-
Bryan O'Sullivan
-
Khudyakov Alexey