cborg icon indicating copy to clipboard operation
cborg copied to clipboard

More informative error messages in Generic-derived instances

Open Shimuuar opened this issue 6 years ago • 1 comments

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

Shimuuar avatar Oct 16 '18 14:10 Shimuuar

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:

  1. 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.

  2. 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?

Shimuuar avatar Feb 07 '20 16:02 Shimuuar