cborg
cborg copied to clipboard
More informative error messages in Generic-derived instances
Short demonstration:
data OldFoo = OldFoo Int Int
deriving (Show,Generic)
data NewFoo = NewFoo Int Int Int
deriving (Show,Generic)
λ> (deserialise . serialise) (OldFoo 1 2) :: NewFoo
*** Exception: DeserialiseFailure 1 "Wrong number of fields: expected=4 got=3"
Such errors happen when someone changes definition of type and you try to decode old data and error message is completely uninformative and finding cause of error is very hard. Especially if you have deeply nested data types. It would be nice to include at least name of type into error message
I spent another hour what does DeserialiseFailure 1 "expect list of length 2"
mean. I decided that enough is enough. I see two possible strategies for fixing this:
-
Modify classes for generics to pass type name and constructor name around. It's possible and have half-done prototype. But in order to get good error messages we'll need also primitives with custom error messages. Without that if decoder encounters bytestring instead of list it will just error with
list is expected
without mentioning context. -
Add primitive
withError :: (String -> String) -> Decoder s a -> Decoder s a
which modify error message produced by decoder which is passed as second parameter. It however looks like it would require modification of Decoder. And there's possible performance hit. On the other hand it's more composable approach to error handling
What's your opinion on matter?