17

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
Titou
  • 968
  • 10
  • 16
  • There was a [feature request about this](https://github.com/bos/aeson/issues/113), and it had been merged... Obviously, if we knew the specific context in which this occurs, it would be helpful. – Alec Oct 26 '16 at 01:45
  • By the way, hdgarrood (user:1434220) should be awarded the bounty, he's the author of the library. – Titou Nov 02 '16 at 10:24
  • @Titou: can you add your edit as an answer? That will be very helpful for future visitors. – static_rtti Nov 02 '16 at 10:40

2 Answers2

9

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.

J. Abrahamson
  • 72,246
  • 9
  • 135
  • 180
  • Is it not equivalent to returning to Parsec (in terms of code complexity and performance) ? – Titou Nov 28 '13 at 16:47
  • You can do better performance, I've been on my phone so I kept it overly simple. The heart of it is that you'll have a large number of built in JSON type parsers which are more convenient and easier to read than Parsec. I wouldn't say it's comparable. – J. Abrahamson Nov 28 '13 at 17:24
1

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.

Titou
  • 968
  • 10
  • 16