UNPKG

polite-json

Version:

JSON.parse and stringify with better errors that respects formatting

102 lines (74 loc) 3.69 kB
# polite-json This is a Node.js library for getting nicer errors out of `JSON.parse()`, including context and position of the parse errors. It also preserves the newline and indentation styles of the JSON data, by putting them in the object or array in the `Symbol.for('indent')` and `Symbol.for('newline')` properties, so that if you `stringify()` the object you parsed, it'll be formatted with the same indentation and newlines (in most cases, it's not a super clever streaming in-place editor, it just uses the first line break and indentation it sees). ## Install `$ npm install --save polite-json` ### Example ```js import { parse, parseNoExceptions, stringify } from 'polite-json' // or: const { parse, stringify } = require('polite-json') parse('"foo"') // returns the string 'foo' const obj = parse('{\r\n\t"hello": "world"\r\n}') // { hello: 'world' } stringify(obj) // stringifies with \r\n line breaks, \t indentation parse('garbage') // more useful error message parseNoExceptions('garbage') // no error, just undefined ``` ### Features - Like JSON.parse, but the errors are better, and style choices are (mostly) preserved. - Strips a leading byte-order-mark that you sometimes get reading files. - Has a `noExceptions` method that returns undefined rather than throwing. - Attaches the newline character(s) used to the `Symbol.for('newline')` property on objects and arrays. - Attaches the indentation character(s) used to the `Symbol.for('indent')` property on objects and arrays. ## Indentation Indentation and newline information is saved on the `Symbol.for('indent')` and `Symbol.for('newline')` properties, respectively. This is usually not a problem for JSON objects, since JSON ignores symbols, but if you are using them for some other purpose, it could cause weird behavior. Indentation is determined by looking at the whitespace between the initial `{` and `[` and the character that follows it. If you have lots of weird inconsistent indentation, then it won't track that or give you any way to preserve it. Whether this is a bug or a feature is debatable ;) ### API #### `parse(txt, reviver = null, context = 20)` Works just like `JSON.parse`, but will include a bit more information when an error happens, and attaches a `Symbol.for('indent')` and `Symbol.for('newline')` on objects and arrays. This throws a `JSONParseError`. #### `parseNoExceptions(txt, reviver = null)` Works just like `JSON.parse`, but will return `undefined` rather than throwing an error. #### `class JSONParseError(er, text, context = 20, caller = null)` Extends the JavaScript `SyntaxError` class to parse the message and provide better metadata. Pass in the error thrown by the built-in `JSON.parse`, and the text being parsed, and it'll parse out the bits needed to be helpful. `context` defaults to 20. The `er` parameter is attached as the `JSONParseError.cause` property. This is used to provide a reference to the original system error that was raised by `JSON.parse()`. Set a `caller` function to trim internal implementation details out of the stack trace. When calling `parseJson`, this is set to the `parseJson` function. If not set, then the constructor defaults to itself, so the stack trace will point to the spot where you call `new JSONParseError`. #### `stringify(obj, reviver = undefined, indent = undefined)` If the object was parsed using the `parse()` methods in this library, then it will default to using the same indentation and newline strings that were detected, if relevant. If `indent` is set, then the stored formatting information is ignored, and `\n` newlines will be used. A final newline will be appended if indentation is used.