Skip to content

Commit 3f8a420

Browse files
authored
Merge pull request #695 from FintanH/fintan/better-errors
Add labels to json object and list parsing
2 parents d95d985 + d1364e4 commit 3f8a420

File tree

3 files changed

+21
-6
lines changed

3 files changed

+21
-6
lines changed

Data/Aeson/Parser/Internal.hs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,9 @@ objectValues str val = do
123123
-- Why use acc pattern here, you may ask? because 'H.fromList' use 'unsafeInsert'
124124
-- and it's much faster because it's doing in place update to the 'HashMap'!
125125
loop acc = do
126-
k <- str <* skipSpace <* char ':'
127-
v <- val <* skipSpace
128-
ch <- A.satisfy $ \w -> w == COMMA || w == CLOSE_CURLY
126+
k <- (str A.<?> "object key") <* skipSpace <* (char ':' A.<?> "':'")
127+
v <- (val A.<?> "object value") <* skipSpace
128+
ch <- A.satisfy (\w -> w == COMMA || w == CLOSE_CURLY) A.<?> "',' or '}'"
129129
let acc' = (k, v) : acc
130130
if ch == COMMA
131131
then skipSpace >> loop acc'
@@ -149,8 +149,8 @@ arrayValues val = do
149149
else loop [] 1
150150
where
151151
loop acc !len = do
152-
v <- val <* skipSpace
153-
ch <- A.satisfy $ \w -> w == COMMA || w == CLOSE_SQUARE
152+
v <- (val A.<?> "json list value") <* skipSpace
153+
ch <- A.satisfy (\w -> w == COMMA || w == CLOSE_SQUARE) A.<?> "',' or ']'"
154154
if ch == COMMA
155155
then skipSpace >> loop (v:acc) (len+1)
156156
else return (Vector.reverse (Vector.fromListN len (v:acc)))
@@ -275,7 +275,12 @@ eitherDecodeWith p to s =
275275
L.Done _ v -> case to v of
276276
ISuccess a -> Right a
277277
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
279284
{-# INLINE eitherDecodeWith #-}
280285

281286
eitherDecodeStrictWith :: Parser Value -> (Value -> IResult a) -> B.ByteString

tests/ErrorMessages.hs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ outputGeneric choice = concat
117117
, "{\"record\": {}, \"W\":{}}"
118118
, "{}"
119119
, "[]"
120+
, "{\"unary\""
121+
, "{\"unary\":"
122+
, "{\"unary\":1"
120123
]
121124

122125
, testWithSomeType "SomeType (two-element array)"
@@ -129,6 +132,8 @@ outputGeneric choice = concat
129132
, "[null, 0]"
130133
, "[]"
131134
, "{}"
135+
, "[1"
136+
, "[1,"
132137
]
133138

134139
, testWith "EitherTextInt"

tests/golden/generic.expected

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,18 @@ Error in $: parsing Types.SomeType failed, expected an Object with a single pair
1919
Error in $: parsing Types.SomeType failed, expected an Object with a single pair, but found 2 pairs
2020
Error in $: parsing Types.SomeType failed, expected an Object with a single pair, but found 0 pairs
2121
Error 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 '}'
2225
SomeType (two-element array)
2326
Error in $[1]: parsing Int failed, expected Number, but encountered Boolean
2427
Error in $[1]: parsing Types.SomeType(Record) failed, expected Object, but encountered Null
2528
Error in $[0]: parsing Types.SomeType failed, expected tag of the 2-element Array to be one of ["nullary","unary","product","record","list"], but found tag "X"
2629
Error in $[0]: parsing Types.SomeType failed, tag element is not a String
2730
Error in $: parsing Types.SomeType failed, expected a 2-element Array, but encountered an Array of length 0
2831
Error 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
2934
EitherTextInt
3035
Error in $: parsing Types.EitherTextInt(NoneNullary) failed, expected tag "nonenullary", but found tag "X"
3136
Error in $: parsing Types.EitherTextInt(NoneNullary) failed, expected String, but encountered Array

0 commit comments

Comments
 (0)