on master help sign in
Merge pull request #695 from FintanH/fintan/better-errors
3f8a420Adam Bergmark
Data/Aeson/Parser/Internal.hs+11−6
@@ -123,9 +123,9 @@ objectValues str val = do
123 -- Why use acc pattern here, you may ask? because 'H.fromList' use 'unsafeInsert'
123 -- Why use acc pattern here, you may ask? because 'H.fromList' use 'unsafeInsert'
124 -- and it's much faster because it's doing in place update to the 'HashMap'!
124 -- and it's much faster because it's doing in place update to the 'HashMap'!
125 loop acc = do
125 loop acc = do
126− k <- str <* skipSpace <* char ':'
126+ k <- (str A.<?> "object key") <* skipSpace <* (char ':' A.<?> "':'")
127− v <- val <* skipSpace
127+ v <- (val A.<?> "object value") <* skipSpace
128− ch <- A.satisfy $ \w -> w == COMMA || w == CLOSE_CURLY
128+ ch <- A.satisfy (\w -> w == COMMA || w == CLOSE_CURLY) A.<?> "',' or '}'"
129 let acc' = (k, v) : acc
129 let acc' = (k, v) : acc
130 if ch == COMMA
130 if ch == COMMA
131 then skipSpace >> loop acc'
131 then skipSpace >> loop acc'
@@ -149,8 +149,8 @@ arrayValues val = do
149 else loop [] 1
149 else loop [] 1
150 where
150 where
151 loop acc !len = do
151 loop acc !len = do
152− v <- val <* skipSpace
152+ v <- (val A.<?> "json list value") <* skipSpace
153− ch <- A.satisfy $ \w -> w == COMMA || w == CLOSE_SQUARE
153+ ch <- A.satisfy (\w -> w == COMMA || w == CLOSE_SQUARE) A.<?> "',' or ']'"
154 if ch == COMMA
154 if ch == COMMA
155 then skipSpace >> loop (v:acc) (len+1)
155 then skipSpace >> loop (v:acc) (len+1)
156 else return (Vector.reverse (Vector.fromListN len (v:acc)))
156 else return (Vector.reverse (Vector.fromListN len (v:acc)))
@@ -275,7 +275,12 @@ eitherDecodeWith p to s =
275 L.Done _ v -> case to v of
275 L.Done _ v -> case to v of
276 ISuccess a -> Right a
276 ISuccess a -> Right a
277 IError path msg -> Left (path, msg)
277 IError path msg -> Left (path, msg)
278− L.Fail _ _ msg -> Left ([], msg)
278+ L.Fail _ ctx msg -> Left ([], buildMsg ctx msg)
279+ where
280+ buildMsg :: [String] -> String -> String
281+ buildMsg [] msg = msg
282+ buildMsg (expectation:_) msg =
283+ msg ++ ". Expecting " ++ expectation
279{-# INLINE eitherDecodeWith #-}
284{-# INLINE eitherDecodeWith #-}
280
285
281eitherDecodeStrictWith :: Parser Value -> (Value -> IResult a) -> B.ByteString
286eitherDecodeStrictWith :: Parser Value -> (Value -> IResult a) -> B.ByteString
tests/ErrorMessages.hs+5
@@ -117,6 +117,9 @@ outputGeneric choice = concat
117 , "{\"record\": {}, \"W\":{}}"
117 , "{\"record\": {}, \"W\":{}}"
118 , "{}"
118 , "{}"
119 , "[]"
119 , "[]"
120+ , "{\"unary\""
121+ , "{\"unary\":"
122+ , "{\"unary\":1"
120 ]
123 ]
121
124
122 , testWithSomeType "SomeType (two-element array)"
125 , testWithSomeType "SomeType (two-element array)"
@@ -129,6 +132,8 @@ outputGeneric choice = concat
129 , "[null, 0]"
132 , "[null, 0]"
130 , "[]"
133 , "[]"
131 , "{}"
134 , "{}"
135+ , "[1"
136+ , "[1,"
132 ]
137 ]
133
138
134 , testWith "EitherTextInt"
139 , testWith "EitherTextInt"
tests/golden/generic.expected+5
@@ -19,6 +19,9 @@ Error in $: parsing Types.SomeType failed, expected an Object with a single pair
19Error in $: parsing Types.SomeType failed, expected an Object with a single pair, but found 2 pairs
19Error in $: parsing Types.SomeType failed, expected an Object with a single pair, but found 2 pairs
20Error in $: parsing Types.SomeType failed, expected an Object with a single pair, but found 0 pairs
20Error in $: parsing Types.SomeType failed, expected an Object with a single pair, but found 0 pairs
21Error in $: parsing Types.SomeType failed, expected Object, but encountered Array
21Error in $: parsing Types.SomeType failed, expected Object, but encountered Array
22+Error in $: not enough input. Expecting ':'
23+Error in $: not enough input. Expecting object value
24+Error in $: not enough input. Expecting ',' or '}'
22SomeType (two-element array)
25SomeType (two-element array)
23Error in $[1]: parsing Int failed, expected Number, but encountered Boolean
26Error in $[1]: parsing Int failed, expected Number, but encountered Boolean
24Error in $[1]: parsing Types.SomeType(Record) failed, expected Object, but encountered Null
27Error in $[1]: parsing Types.SomeType(Record) failed, expected Object, but encountered Null
@@ -26,6 +29,8 @@ Error in $[0]: parsing Types.SomeType failed, expected tag of the 2-element Arra
26Error in $[0]: parsing Types.SomeType failed, tag element is not a String
29Error in $[0]: parsing Types.SomeType failed, tag element is not a String
27Error in $: parsing Types.SomeType failed, expected a 2-element Array, but encountered an Array of length 0
30Error in $: parsing Types.SomeType failed, expected a 2-element Array, but encountered an Array of length 0
28Error in $: parsing Types.SomeType failed, expected Array, but encountered Object
31Error in $: parsing Types.SomeType failed, expected Array, but encountered Object
32+Error in $: not enough input. Expecting ',' or ']'
33+Error in $: not enough input. Expecting json list value
29EitherTextInt
34EitherTextInt
30Error in $: parsing Types.EitherTextInt(NoneNullary) failed, expected tag "nonenullary", but found tag "X"
35Error in $: parsing Types.EitherTextInt(NoneNullary) failed, expected tag "nonenullary", but found tag "X"
31Error in $: parsing Types.EitherTextInt(NoneNullary) failed, expected String, but encountered Array
36Error in $: parsing Types.EitherTextInt(NoneNullary) failed, expected String, but encountered Array