@@ -1,112 +1,225 @@
1{-# OPTIONS_GHC -Wall #-}
1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Reporting.Error.Json
3module Reporting.Error.Json
6− , DecodeExpectation(..)
8− , toReport
4+ ( toReport
13−import qualified Data.Utf8 as Utf8
9+import qualified Data.Char as Char
14−import Data.Word (Word16)
10+import qualified Data.Map as Map
12+import Json.Decode (Error(..), Problem(..), DecodeExpectation(..), ParseError(..), StringProblem(..))
13+import qualified Reporting.Annotation as A
16−import qualified Reporting.Report as Report
14+import qualified Reporting.Doc as D
15+import qualified Reporting.Exit.Help as Help
16+import qualified Reporting.Render.Code as Code
20−-- ERROR
20+-- TO REPORT
24− = DecodeProblem (Problem e)
25− | ParseProblem ParseError
32−data Problem e
23+toReport :: FilePath -> Error x -> Help.Report
33− = Field Utf8.String (Problem e)
24+toReport path err =
34− | Index Int (Problem e)
25+ case err of
35− | OneOf (Problem e) [Problem e]
26+ DecodeProblem bytes problem ->
36− | Failure e
27+ problemToReport (Code.toSource bytes) problem
37− | Expecting DecodeExpectation
29+ ParseProblem bytes parseError ->
30+ parseErrorToReport path (Code.toSource bytes) parseError
40−data DecodeExpectation
46− | TObjectWith Utf8.String
34+-- PARSE ERROR TO REPORT
37+parseErrorToReport :: FilePath -> Code.Source -> ParseError -> Help.Report
38+parseErrorToReport path source parseError =
40+ toSnippet title row col pair =
41+ let pos = A.Position row col in
42+ Help.jsonReport title (Just path) $
43+ Code.toSnippet source (A.Region pos pos) Nothing pair
47+ toSnippet "EXPECTING A VALUE" row col
49+ D.reflow $ "I was expecting to see a JSON value next:"
53+ ["Try","something","like",D.dullyellow "\"this\"","or"
54+ ,D.dullyellow "42","to","move","on","to","better","hints!"
57+ "The JSON specification does not allow trailing commas, so you can sometimes\
58+ \ get this error in arrays that have an extra comma at the end. In that case,\
59+ \ remove that last comma or add another array entry after it!"
54−data ParseError
63+ ObjectField row col ->
55− = PIndex Int ParseError Row Col
64+ toSnippet "UNFINISHED OBJECT" row col
56− | PField Utf8.String ParseError Row Col
65+ (
57− | ObjectStart Row Col
66+ D.reflow $ "I was partway through parsing a JSON object when I got stuck here:"
58− | ObjectMore Row Col
67+ ,
59− | ObjectEnd Row Col
68+ D.stack
60− | ArrayStart Row Col
69+ [ D.reflow $ "I was expecting to see a field name next."
61− | ArrayMore Row Col
70+ , objectNote
62− | ArrayEnd Row Col
71+ ]
63− | StringStart Row Col
72+ )
66− | NoLeadingZeros Row Col
74+ ObjectColon row col ->
75+ toSnippet "EXPECTING COLON" row col
77+ D.reflow $ "I was partway through parsing a JSON object when I got stuck here:"
80+ [ D.reflow $ "I was expecting to see a colon next."
75−type Row = Word16
85+ ObjectEnd row col ->
76−type Col = Word16
86+ toSnippet "UNFINISHED OBJECT" row col
88+ D.reflow $ "I was partway through parsing a JSON object when I got stuck here:"
92+ "I was expecting to see a comma or a closing curly brace next."
94+ "Is a comma missing on the previous line? Is an array missing a closing square\
95+ \ bracket? It is often something tricky like that!"
101+ toSnippet "UNFINISHED ARRAY" row col
103+ D.reflow $ "I was partway through parsing a JSON array when I got stuck here:"
106+ [ D.reflow $ "I was expecting to see a comma or a closing square bracket next."
108+ "Is a comma missing on the previous line? It is often something like that!"
112+ StringProblem stringProblem row col ->
113+ case stringProblem of
115+ toSnippet "ENDLESS STRING" row col
118+ "I got to the end of the line without seeing the closing double quote:"
121+ ["Strings","look","like",D.green "\"this\"","with","double"
122+ ,"quotes","on","each","end.","Is","the","closing","double"
123+ ,"quote","missing","in","your","code?"
127+ BadStringControlChar ->
128+ toSnippet "UNEXPECTED CONTROL CHARACTER" row col
131+ "I ran into a control character unexpectedly:"
134+ "These are characters that represent tabs, backspaces, newlines, and\
135+ \ a bunch of other invisible characters. They all come before 20 in the\
136+ \ ASCII range, and they are disallowed by the JSON specificaiton. Maybe\
137+ \ a copy/paste added one of these invisible characters to your JSON?"
140+ BadStringEscapeChar ->
141+ toSnippet "UNKNOWN ESCAPE" row col
144+ "Backslashes always start escaped characters, but I do not recognize this one:"
148+ "Valid escape characters include:"
149+ , D.dullyellow $ D.indent 4 $ D.vcat $
150+ ["\\\"","\\\\","\\/","\\b","\\f","\\n","\\r","\\t","\\u003D"]
152+ "Do you want one of those instead? Maybe you need \\\\ to escape a backslash?"
156+ BadStringEscapeHex ->
157+ toSnippet "BAD HEX ESCAPE" row col
160+ "This is not a valid hex escape:"
163+ ["Valid","hex","escapes","in","JSON","are","between"
164+ ,D.green "\\u0000","and",D.green "\\uFFFF"
165+ ,"and","always","have","exactly","four","digits."
169+ NoLeadingZeros row col ->
170+ toSnippet "BAD NUMBER" row col
172+ D.reflow $ "Numbers cannot start with zeros like this:"
174+ D.reflow $ "Try deleting the leading zeros?"
178+ toSnippet "UNEXPECTED NUMBER" row col
180+ D.reflow $ "I got stuck while trying to parse this number:"
183+ "I do not accept floating point numbers like 3.1415 right now. That kind\
184+ \ of JSON value is not needed for any of the uses that Elm has for now."
188+ toSnippet "JSON PROBLEM" row col
190+ D.reflow $ "I was partway through parsing some JSON when I got stuck here:"
193+ "I am not really sure what is wrong. This sometimes means there is extra\
194+ \ stuff after a valid JSON value?"
201+ [ D.toSimpleNote $ "Here is an example of a valid JSON object for reference:"
204+ , D.indent 6 $ D.dullyellow "\"name\"" <> ": " <> D.dullyellow "\"Tom\"" <> ","
205+ , D.indent 6 $ D.dullyellow "\"age\"" <> ": " <> D.dullyellow "42"
209+ "Notice that (1) the field names are in double quotes and (2) there is no\
210+ \ trailing comma after the last entry. Both are strict requirements in JSON!"
83−toReport :: Error e -> Report.Report
85− error "TODO Reporting.Error.Json.toReport" err
218+problemToReport :: Code.Source -> Problem x -> Help.Report
219+problemToReport source problem =
220+ error "TODO problemToReport" source problem
94− = BadJson Syntax.Error
95− | BadContent (Json.Error e)
102−toDoc :: String -> Code.Source -> (e -> [D.Doc]) -> Error e -> D.Doc
103−toDoc rootName source userErrorToDocs err =
105− BadJson syntaxError ->
106− case Syntax.toReport source syntaxError of
107− Report.Report _ _ _ doc ->
110 BadContent jsonError ->
223 BadContent jsonError ->
111 case flatten jsonError of
224 case flatten jsonError of
@@ -312,9 +425,9 @@ addName name err subErrors =
312 Map.alter subAdd name subErrors
425 Map.alter subAdd name subErrors
315−fieldToName :: Text.Text -> String
428+fieldToName :: [Char] -> String
316fieldToName field =
429fieldToName field =
317− case Text.unpack field of
430+ case field of
@@ -328,5 +441,4 @@ fieldToName field =
328indexToName :: Int -> String
441indexToName :: Int -> String
329indexToName index =
442indexToName index =
330 "[" ++ show index ++ "]"
443 "[" ++ show index ++ "]"