Fault tolerant JSON parsing
aeson, haskell, json
Solution
If you are using GHC 7.2 or 7.4, the new generics support in `aeson` doesn't check for extra fields. I'm not sure if this is by design or not but we use it for the same reason.
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Data.Aeson
import qualified Data.Aeson.Types
import Data.Attoparsec
import qualified Data.ByteString as BS
import Data.ByteString.Char8 ()
import GHC.Generics
data MyRecord = MyRecord
{ field1 :: Int
} deriving (Generic, Show)
instance FromJSON MyRecord
myRecordFromJSONString :: BS.ByteString -> Maybe MyRecord
myRecordFromJSONString s = case Data.Attoparsec.parse json s of
Done _rest res -> Data.Aeson.Types.parseMaybe parseJSON res
_ -> Nothing
main :: IO ()
main = do
let parsed = myRecordFromJSONString "{ \"field1\": 1, \"field2\": 2 }"
print parsed
Running this would fail with the TH derived instance due to 'field2' not existing in the record. The `Generic` instance returns the desired result:
Just (MyRecord {field1 = 1})
Problem
I'm using Data.Aeson to parse some JSON into a Record type. From time to time data is added to the JSON and this breaks my code as Aeson complains something to the effect of: expected Object with 21 name/value pairs but got 23 name/value I'd really prefer to parse the JSON in a fault tolerant way -- I don't care if more fields are added to the JSON at a later date, just parse whatever you can! Is there a way to achieve this fault tolerance? Here's my code: ``` myRecordFromJSONString :: BS.ByteString -> Maybe MyRecord myRecordFromJSONString s = case Data.Attoparsec.parse json s of Done _rest res -> Data.Aeson.Types.parseMaybe parseJSON res _ -> Nothing ``` I should add that I'm using deriveJSON from Data.Aeson.TH to generate the parsing code. If I write the FromJSON code manually it's fault tolerant but I'd like to not have to do that...