Tim van der Lippe | efb716a | 2020-12-01 12:54:04 | [diff] [blame] | 1 | # json-parse-even-better-errors |
| 2 | |
| 3 | [`json-parse-even-better-errors`](https://github.com/npm/json-parse-even-better-errors) |
| 4 | is a Node.js library for getting nicer errors out of `JSON.parse()`, |
| 5 | including context and position of the parse errors. |
| 6 | |
| 7 | It also preserves the newline and indentation styles of the JSON data, by |
| 8 | putting them in the object or array in the `Symbol.for('indent')` and |
| 9 | `Symbol.for('newline')` properties. |
| 10 | |
| 11 | ## Install |
| 12 | |
| 13 | `$ npm install --save json-parse-even-better-errors` |
| 14 | |
| 15 | ## Table of Contents |
| 16 | |
| 17 | * [Example](#example) |
| 18 | * [Features](#features) |
| 19 | * [Contributing](#contributing) |
| 20 | * [API](#api) |
| 21 | * [`parse`](#parse) |
| 22 | |
| 23 | ### Example |
| 24 | |
| 25 | ```javascript |
| 26 | const parseJson = require('json-parse-even-better-errors') |
| 27 | |
| 28 | parseJson('"foo"') // returns the string 'foo' |
| 29 | parseJson('garbage') // more useful error message |
| 30 | parseJson.noExceptions('garbage') // returns undefined |
| 31 | ``` |
| 32 | |
| 33 | ### Features |
| 34 | |
| 35 | * Like JSON.parse, but the errors are better. |
| 36 | * Strips a leading byte-order-mark that you sometimes get reading files. |
| 37 | * Has a `noExceptions` method that returns undefined rather than throwing. |
| 38 | * Attaches the newline character(s) used to the `Symbol.for('newline')` |
| 39 | property on objects and arrays. |
| 40 | * Attaches the indentation character(s) used to the `Symbol.for('indent')` |
| 41 | property on objects and arrays. |
| 42 | |
| 43 | ## Indentation |
| 44 | |
| 45 | To preserve indentation when the file is saved back to disk, use |
| 46 | `data[Symbol.for('indent')]` as the third argument to `JSON.stringify`, and |
| 47 | if you want to preserve windows `\r\n` newlines, replace the `\n` chars in |
| 48 | the string with `data[Symbol.for('newline')]`. |
| 49 | |
| 50 | For example: |
| 51 | |
| 52 | ```js |
| 53 | const txt = await readFile('./package.json', 'utf8') |
| 54 | const data = parseJsonEvenBetterErrors(txt) |
| 55 | const indent = Symbol.for('indent') |
| 56 | const newline = Symbol.for('newline') |
| 57 | // .. do some stuff to the data .. |
| 58 | const string = JSON.stringify(data, null, data[indent]) + '\n' |
| 59 | const eolFixed = data[newline] === '\n' ? string |
| 60 | : string.replace(/\n/g, data[newline]) |
| 61 | await writeFile('./package.json', eolFixed) |
| 62 | ``` |
| 63 | |
| 64 | Indentation is determined by looking at the whitespace between the initial |
| 65 | `{` and `[` and the character that follows it. If you have lots of weird |
| 66 | inconsistent indentation, then it won't track that or give you any way to |
| 67 | preserve it. Whether this is a bug or a feature is debatable ;) |
| 68 | |
| 69 | ### API |
| 70 | |
| 71 | #### <a name="parse"></a> `parse(txt, reviver = null, context = 20)` |
| 72 | |
| 73 | Works just like `JSON.parse`, but will include a bit more information when |
| 74 | an error happens, and attaches a `Symbol.for('indent')` and |
| 75 | `Symbol.for('newline')` on objects and arrays. This throws a |
| 76 | `JSONParseError`. |
| 77 | |
| 78 | #### <a name="parse"></a> `parse.noExceptions(txt, reviver = null)` |
| 79 | |
| 80 | Works just like `JSON.parse`, but will return `undefined` rather than |
| 81 | throwing an error. |
| 82 | |
| 83 | #### <a name="jsonparseerror"></a> `class JSONParseError(er, text, context = 20, caller = null)` |
| 84 | |
| 85 | Extends the JavaScript `SyntaxError` class to parse the message and provide |
| 86 | better metadata. |
| 87 | |
| 88 | Pass in the error thrown by the built-in `JSON.parse`, and the text being |
| 89 | parsed, and it'll parse out the bits needed to be helpful. |
| 90 | |
| 91 | `context` defaults to 20. |
| 92 | |
| 93 | Set a `caller` function to trim internal implementation details out of the |
| 94 | stack trace. When calling `parseJson`, this is set to the `parseJson` |
| 95 | function. If not set, then the constructor defaults to itself, so the |
| 96 | stack trace will point to the spot where you call `new JSONParseError`. |