Google Groupes

Json.Decode without failing on the first error?


Rupert Smith 9 nov. 2017 04:39
Envoyé au groupe : Elm Discuss
Hi,

Has anyone any thoughts on writing a Json decoder that keeps going when it encounters errors, until it gets all the way to the end of the data, and then produces an error report detailing all of the errors that it encountered, rather than just the first one?

Here is an example data model for discussion with a decoder for it:

import Set exposing (Set)
import Dict exposing (Dict)
import Json.Decode as Decode exposing (..)
import Json.Decode.Extra exposing ((|:), withDefault)

type Item =
    Item
    {  name : Maybe String
    , description : Maybe String
    , price : Maybe Int
    , sku : Maybe String
    , stockAvailable : Maybe Int
    , internationalShipping : Maybe Bool
    }

itemDecoder : Decoder Item
itemDecoder =
    (Decode.succeed
        (\name description price sku stockAvailable internationalShipping ->
            Item
                {
                name = name
                ,description = description
                ,price = price
                ,sku = sku
                ,stockAvailable = stockAvailable
                ,internationalShipping = internationalShipping
                }
        )
    )
        |: Decode.maybe (field "name" Decode.string)
        |: Decode.maybe (field "description" Decode.string)
        |: Decode.maybe (field "price" Decode.int)
        |: Decode.maybe (field "sku" Decode.string)
        |: Decode.maybe (field "stock-available" Decode.int)
        |: Decode.maybe (field "international-shipping" Decode.bool)


You can see that in my data model, I made all the fields Maybes. This is because I wanted to not fail if a field was missing, not because the fields in this data model are really optional.

I would rather that the fields were not Maybes, and that when applying itemDecoder to some Json using Decode.decodeString or Decode.decodeValue that I would get either 

Ok { ... the data .. } 

or 

Error [ "price is not an int", "field order-date is not allowed", "field sku is missing" ]

To achieve this I think I would need to write a more sophisticated version of the '|:' operator from json-extra, but not sure exactly how.

Rupert