Skip to content

Latest commit

 

History

History
267 lines (205 loc) · 9.3 KB

README.md

File metadata and controls

267 lines (205 loc) · 9.3 KB
modern-errors logo

Node Browsers TypeScript Codecov Minified size Twitter Medium

modern-errors plugin to serialize/parse errors.

This adds error.toJSON() and BaseError.parse() to serialize/parse errors to/from plain objects.

Features

Example

Adding the plugin to modern-errors.

import ModernError from 'modern-errors'
import modernErrorsSerialize from 'modern-errors-serialize'

export const BaseError = ModernError.subclass('BaseError', {
  plugins: [modernErrorsSerialize],
})
// ...

Serializing errors to plain objects.

const error = new InputError('Wrong file.', { props: { filePath } })
const errorObject = error.toJSON()
// { name: 'InputError', message: 'Wrong file', stack: '...', filePath: '...' }
const errorString = JSON.stringify(error)
// '{"name":"InputError",...}'

Parsing errors from plain objects.

const newErrorObject = JSON.parse(errorString)
const newError = BaseError.parse(newErrorObject)
// InputError: Wrong file.
//     at ...
//   filePath: '...'

Install

npm install modern-errors-serialize

This package works in both Node.js >=14.18.0 and browsers. It is an ES module and must be loaded using an import or import() statement, not require().

API

modernErrorsSerialize

Type: Plugin

Plugin object to pass to the plugins option of ErrorClass.subclass().

error.toJSON()

Return value: ErrorObject

Converts errors to plain objects that are serializable to JSON (or YAML, etc.). This is automatically called by JSON.stringify().

All error properties are kept. Plugin options are also preserved.

BaseError.parse(value)

If value is an error plain object, converts it to an error instance. Otherwise, recurse over value and parse any nested error plain object.

The original error classes are preserved.

Usage

JSON safety

Error plain objects are always safe to serialize with JSON.

const error = new InputError('Wrong file.')
error.cycle = error

// Cycles make `JSON.stringify()` throw, so they are removed
console.log(error.toJSON().cycle) // undefined

Deep serialization/parsing

Objects and arrays are deeply serialized and parsed.

const error = new InputError('Wrong file.')
const deepArray = [{}, { error }]

const jsonString = JSON.stringify(deepArray)
const newDeepArray = JSON.parse(jsonString)

const newError = BaseError.parse(newDeepArray)[1].error
// InputError: Wrong file.
//     at ...

Custom serialization/parsing

Errors are converted to/from plain objects, not strings. This allows any serialization/parsing logic to be performed.

import { dump, load } from 'js-yaml'

const error = new InputError('Wrong file.')
const errorObject = error.toJSON()
const errorYamlString = dump(errorObject)
// name: InputError
// message: Wrong file.
// stack: InputError: Wrong file. ...
const newErrorObject = load(errorYamlString)
const newError = BaseError.parse(newErrorObject) // InputError: Wrong file.

Additional error properties

const error = new InputError('Wrong file.', { props: { prop: true } })
const errorObject = error.toJSON()
console.log(errorObject.prop) // true
const newError = BaseError.parse(errorObject)
console.log(newError.prop) // true

Aggregate errors

const error = new InputError('Wrong file.', {
  errors: [new ExampleError('one'), new ExampleError('two')],
})

const errorObject = error.toJSON()
// {
//   name: 'InputError',
//   message: 'Wrong file.',
//   stack: '...',
//   errors: [{ name: 'ExampleError', message: 'one', stack: '...' }, ...],
// }
const newError = BaseError.parse(errorObject)
// InputError: Wrong file.
//   [errors]: [ExampleError: one, ExampleError: two]

Constructors

If an error with a custom class is parsed, its custom constructor is not called. However, any property previously set by that constructor is still preserved, providing it is serializable and enumerable.

const InputError = BaseError.subclass('InputError', {
  custom: class extends BaseError {
    constructor(message, options, prop) {
      super(message, options, prop)
      this.prop = prop
    }
  },
})

const error = new InputError('Wrong file.', {}, true)
const errorObject = error.toJSON()
// `constructor(message, options, prop)` is not called
const newError = BaseError.parse(errorObject)
// But properties set by that `constructor(...)` are kept
console.log(newError.prop) // true

Related projects

Support

For any question, don't hesitate to submit an issue on GitHub.

Everyone is welcome regardless of personal background. We enforce a Code of conduct in order to promote a positive and inclusive environment.

Contributing

This project was made with ❤️. The simplest way to give back is by starring and sharing it online.

If the documentation is unclear or has a typo, please click on the page's Edit button (pencil icon) and suggest a correction.

If you would like to help us fix a bug or add a new feature, please check our guidelines. Pull requests are welcome!