0
# Parse JSON
1
2
Parse JSON is a JavaScript library that enhances the standard JSON.parse() functionality with more helpful error messages and visual code frames for debugging. It generates user-friendly error messages with code frames that highlight the exact location of JSON syntax errors, making it particularly valuable for development tools, configuration parsers, CLI applications, and any system that needs to provide clear feedback about JSON parsing failures.
3
4
## Package Information
5
6
- **Package Name**: parse-json
7
- **Package Type**: npm
8
- **Language**: JavaScript/TypeScript
9
- **Installation**: `npm install parse-json`
10
11
## Core Imports
12
13
```javascript
14
import parseJson, { JSONError } from "parse-json";
15
```
16
17
For CommonJS:
18
19
```javascript
20
const parseJson = require("parse-json");
21
const { JSONError } = require("parse-json");
22
```
23
24
## Architecture
25
26
Parse JSON is built around two main components:
27
28
- **parseJson Function**: The main parsing function that wraps JSON.parse() with enhanced error handling
29
- **JSONError Class**: A custom error class that extends Error with additional properties for debugging
30
- **Error Enhancement**: Uses @babel/code-frame for visual error highlighting and index-to-position for accurate location mapping
31
- **Legacy Support**: Maintains backwards compatibility with older constructor patterns
32
33
## Basic Usage
34
35
```javascript
36
import parseJson, { JSONError } from "parse-json";
37
38
const invalidJson = '{\n\t"foo": true,\n}';
39
40
try {
41
// Standard JSON.parse would throw a less helpful error
42
const result = parseJson(invalidJson);
43
} catch (error) {
44
if (error instanceof JSONError) {
45
console.log(error.message);
46
// Output:
47
// Expected double-quoted property name in JSON at position 16 (line 3 column 1)
48
//
49
// 1 | {
50
// 2 | "foo": true,
51
// > 3 | }
52
// | ^
53
}
54
}
55
56
// Include filename for better debugging context
57
try {
58
const result = parseJson(invalidJson, 'config.json');
59
} catch (error) {
60
console.log(error.message);
61
// Output includes filename: "... in config.json"
62
}
63
```
64
65
## Capabilities
66
67
### JSON Parsing with Enhanced Errors
68
69
The main parsing function that provides enhanced error messages with visual code frames.
70
71
```javascript { .api }
72
/**
73
* Parse JSON with more helpful errors
74
* @param {string} string - A valid JSON string to parse
75
* @param {Reviver} [reviver] - Optional reviver function (same as JSON.parse)
76
* @param {string} [filename] - Optional filename for error context
77
* @returns {JsonObject} Parsed JSON object
78
* @throws {JSONError} When there is a parsing error
79
*/
80
function parseJson(string: string, reviver?: Reviver, filename?: string): JsonObject;
81
82
/**
83
* Parse JSON with filename as second parameter (overload)
84
* @param {string} string - A valid JSON string to parse
85
* @param {string} [filename] - Optional filename for error context
86
* @returns {JsonObject} Parsed JSON object
87
* @throws {JSONError} When there is a parsing error
88
*/
89
function parseJson(string: string, filename?: string): JsonObject;
90
```
91
92
**Usage Examples:**
93
94
```javascript
95
import parseJson from "parse-json";
96
97
// Basic parsing
98
const data = parseJson('{"name": "Alice", "age": 30}');
99
100
// With reviver function
101
const dataWithReviver = parseJson('{"date": "2023-01-01"}', (key, value) => {
102
if (key === 'date') return new Date(value);
103
return value;
104
});
105
106
// With filename for better error context
107
const config = parseJson(configString, 'app-config.json');
108
109
// Filename as second parameter (alternative syntax)
110
const userdata = parseJson(jsonString, 'users.json');
111
```
112
113
### Enhanced Error Handling
114
115
Custom error class with detailed error information and visual code frames.
116
117
```javascript { .api }
118
/**
119
* Custom error class for JSON parsing errors
120
* Exposed for instanceof checking and error handling
121
*/
122
class JSONError extends Error {
123
/**
124
* The error name, always "JSONError"
125
*/
126
name: "JSONError";
127
128
/**
129
* The filename displayed in the error message, if provided
130
*/
131
fileName?: string;
132
133
/**
134
* Enhanced error message including code frame and filename context
135
* Supports both getter and setter behavior
136
*/
137
message: string;
138
139
/**
140
* The printable section of JSON with syntax highlighting that shows the error
141
* @readonly
142
*/
143
readonly codeFrame?: string;
144
145
/**
146
* The raw version of codeFrame without ANSI color codes
147
* @readonly
148
*/
149
readonly rawCodeFrame?: string;
150
151
/**
152
* The original JSON.parse() SyntaxError that caused this error
153
*/
154
cause?: SyntaxError;
155
156
/**
157
* Constructor for JSONError
158
* @param messageOrOptions - Either a string message (legacy) or options object
159
*/
160
constructor(messageOrOptions: string | JSONErrorOptions);
161
}
162
163
/**
164
* Options for creating a JSONError with enhanced features
165
*/
166
interface JSONErrorOptions {
167
/** The original JSON.parse() error */
168
jsonParseError: SyntaxError;
169
/** Optional filename for error context */
170
fileName?: string;
171
/** The input JSON string that caused the error */
172
input: string;
173
}
174
```
175
176
**Usage Examples:**
177
178
```javascript
179
import parseJson, { JSONError } from "parse-json";
180
181
try {
182
parseJson('{"invalid": json}');
183
} catch (error) {
184
if (error instanceof JSONError) {
185
// Access error properties
186
console.log('Error name:', error.name); // "JSONError"
187
console.log('Filename:', error.fileName); // undefined or specified filename
188
console.log('Enhanced message:', error.message); // Full message with code frame
189
console.log('Code frame:', error.codeFrame); // Highlighted code frame
190
console.log('Raw code frame:', error.rawCodeFrame); // Code frame without colors
191
console.log('Original error:', error.cause); // Original SyntaxError
192
193
// You can modify the filename after catching
194
error.fileName = 'my-config.json';
195
console.log(error.message); // Now includes filename
196
197
// You can also modify the message
198
error.message = 'Custom error message';
199
console.log(error.message); // Custom message with filename and code frame
200
}
201
}
202
203
// Legacy constructor pattern (for backwards compatibility)
204
const legacyError = new JSONError('Custom error message');
205
legacyError.fileName = 'config.json';
206
console.log(legacyError.message); // "Custom error message in config.json"
207
208
// Modern constructor pattern (used internally by parseJson)
209
const modernError = new JSONError({
210
jsonParseError: new SyntaxError('Invalid JSON'),
211
fileName: 'data.json',
212
input: '{"invalid": json}'
213
});
214
console.log(modernError.cause); // Original SyntaxError
215
console.log(modernError.codeFrame); // Generated code frame
216
```
217
218
## Types
219
220
```typescript { .api }
221
/**
222
* Type alias for the reviver parameter, matches JSON.parse signature
223
*/
224
type Reviver = Parameters<typeof JSON['parse']>[1];
225
226
/**
227
* Return type for parsed JSON, using JsonObject from type-fest
228
*/
229
type JsonObject = import('type-fest').JsonObject;
230
231
/**
232
* Options for creating a JSONError with enhanced features
233
*/
234
interface JSONErrorOptions {
235
/** The original JSON.parse() error */
236
jsonParseError: SyntaxError;
237
/** Optional filename for error context */
238
fileName?: string;
239
/** The input JSON string that caused the error */
240
input: string;
241
}
242
```
243
244
## Error Handling Patterns
245
246
The library provides several patterns for handling JSON parsing errors:
247
248
**Basic Error Handling:**
249
```javascript
250
try {
251
const data = parseJson(jsonString);
252
// Process data
253
} catch (error) {
254
if (error instanceof JSONError) {
255
console.error('JSON parsing failed:', error.message);
256
}
257
}
258
```
259
260
**Filename Context:**
261
```javascript
262
// Set filename during parsing
263
try {
264
const config = parseJson(configString, 'app.config.json');
265
} catch (error) {
266
// Error message will include filename
267
}
268
269
// Or set filename after catching
270
try {
271
const data = parseJson(jsonString);
272
} catch (error) {
273
if (error instanceof JSONError) {
274
error.fileName = 'user-data.json';
275
throw error; // Re-throw with filename context
276
}
277
}
278
```
279
280
**Accessing Code Frames:**
281
```javascript
282
try {
283
parseJson(invalidJson);
284
} catch (error) {
285
if (error instanceof JSONError) {
286
// For display in terminals (with colors)
287
console.log(error.codeFrame);
288
289
// For logging or plain text display (without colors)
290
console.log(error.rawCodeFrame);
291
}
292
}
293
```
294
295
**Edge Cases:**
296
```javascript
297
// Empty string handling
298
try {
299
parseJson('');
300
} catch (error) {
301
console.log(error.message); // "Unexpected end of JSON input while parsing empty string"
302
console.log(error.rawCodeFrame); // undefined (no code frame for empty input)
303
}
304
305
// Incomplete JSON
306
try {
307
parseJson('{');
308
} catch (error) {
309
console.log(error.rawCodeFrame); // Shows code frame pointing to the problematic character
310
}
311
312
// Invalid tokens with Unicode representation
313
try {
314
parseJson('a');
315
} catch (error) {
316
console.log(error.message); // 'Unexpected token "a"(\u{61}), "a" is not valid JSON'
317
}
318
```
319
320
## Platform Support
321
322
- **Node.js**: >= 18
323
- **Module Type**: ES Module only (`"type": "module"`)
324
- **Side Effects**: None
325
- **TypeScript**: Full type definitions included