@@ -25,28 +25,47 @@ import {
25
25
Position ,
26
26
} from './interface' ;
27
27
28
+ export class JsonException extends BaseException { }
28
29
29
30
/**
30
31
* A character was invalid in this context.
31
32
*/
32
- export class InvalidJsonCharacterException extends BaseException {
33
+ export class InvalidJsonCharacterException extends JsonException {
34
+ invalidChar : string ;
35
+ line : number ;
36
+ character : number ;
37
+ offset : number ;
38
+
33
39
constructor ( context : JsonParserContext ) {
34
40
const pos = context . previous ;
35
- super ( `Invalid JSON character: ${ JSON . stringify ( _peek ( context ) ) } `
36
- + `at ${ pos . line } :${ pos . character } .` ) ;
41
+ const invalidChar = JSON . stringify ( _peek ( context ) ) ;
42
+ super ( `Invalid JSON character: ${ invalidChar } at ${ pos . line } :${ pos . character } .` ) ;
43
+
44
+ this . invalidChar = invalidChar ;
45
+ this . line = pos . line ;
46
+ this . offset = pos . offset ;
47
+ this . character = pos . character ;
37
48
}
38
49
}
39
50
40
51
41
52
/**
42
53
* More input was expected, but we reached the end of the stream.
43
54
*/
44
- export class UnexpectedEndOfInputException extends BaseException {
55
+ export class UnexpectedEndOfInputException extends JsonException {
45
56
constructor ( _context : JsonParserContext ) {
46
57
super ( `Unexpected end of file.` ) ;
47
58
}
48
59
}
49
60
61
+ /**
62
+ * An error happened within a file.
63
+ */
64
+ export class PathSpecificJsonException extends JsonException {
65
+ constructor ( public path : string , public exception : JsonException ) {
66
+ super ( `An error happened at file path ${ JSON . stringify ( path ) } : ${ exception . message } ` ) ;
67
+ }
68
+ }
50
69
51
70
/**
52
71
* Context passed around the parser with information about where we currently are in the parse.
@@ -860,3 +879,23 @@ export function parseJson(input: string, mode = JsonParseMode.Default): JsonValu
860
879
861
880
return parseJsonAst ( input , mode ) . value ;
862
881
}
882
+
883
+ /**
884
+ * Parse a JSON string into its value. This discards the AST and only returns the value itself.
885
+ * It also absorbs JSON parsing errors and return a new error with the path in it. Useful for
886
+ * showing errors when parsing from a file.
887
+ * @param input The string to parse.
888
+ * @param mode The mode to parse the input with. {@see JsonParseMode}.
889
+ * @returns {JsonValue } The value represented by the JSON string.
890
+ */
891
+ export function parseJsonFile ( input : string , mode = JsonParseMode . Default , path : string ) {
892
+ try {
893
+ return parseJson ( input , mode ) ;
894
+ } catch ( e ) {
895
+ if ( e instanceof JsonException ) {
896
+ throw new PathSpecificJsonException ( path , e ) ;
897
+ } else {
898
+ throw e ;
899
+ }
900
+ }
901
+ }
0 commit comments