Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to trace back parsing errors with Aeson? [+Answer]

Tags:

haskell

aeson

I have big (>1Mb), simple JSON files to parse. I used Aeson, following the tutorial of fpcomplete in their School of Haskell (thank you guys, btw).

As some files (and not all) fail, I suspect the json file not to respect the structure that I am expecting. The error messages I have gotten until now have been

> Failed reading: satisfy

My question is :

  • "How can I get more details on what went wrong ?"

Two levels of debugging/logging/trace constitute my goals :

  • identifying the parser, i.e. which data type could not be parsed (like for Parsec)
  • identifying the data, with a line / char number
like image 329
Titou Avatar asked Nov 28 '13 14:11

Titou


2 Answers

Unfortunately, Aeson trades nice error messages for speed. You can do multiphase decodes, though, so long as your JSON structure is nice and the file is failing your schema, not to parse as JSON altogether.

By multiphase I mean to decode parts of the structure at a time. You can collect the failing Values as well to determine why they were failing your parse.

parse :: FromJSON a => ByteString -> Maybe [Either Value a]
parse s = case decode s of
  Nothing -> fail "could not decode as array"
  Just values -> map tryDecode values
where
  tryDecode :: FromJSON a =>Value -> Either Value a
  tryDecode v = case decode (encode v) of
    Nothing -> Left v
    Just a -> Right a

The decode . encode bit is quite inefficient as it roundtrips through a ByteString, but can be improved by using the more basic Aeson parsers.

like image 61
J. Abrahamson Avatar answered Nov 15 '22 21:11

J. Abrahamson


There is a solution : aeson-better-errors is the nice tutorial of the eponymous package by Harry Garrood. This package proved to be both straightforward to use and provide the very information I was looking for.

One remark : this package will not solve structural errors, like a lacking curly bracket. For that kind of errors you still get InvalidJSON messages that are not localized in the input stream.

like image 35
Titou Avatar answered Nov 15 '22 20:11

Titou