Package Exports
- error-serializer
Readme
Convert errors to/from plain objects.
Features
- Ensures errors are safe to serialize with JSON
- Can be used as
error.toJSON()
- Deep serialization/parsing
- Custom serialization/parsing (e.g. YAML or
process.send()
) - Keeps both native (
TypeError
, etc.) and custom error types - Preserves errors' additional properties
- Works recursively with
error.cause
andAggregateError
- Normalizes invalid errors
- Safe: this never throws
Example
import { serialize, parse } from 'error-serializer'
const error = new TypeError('example')
const errorObject = serialize(error)
// Plain object: { name: 'TypeError', message: 'example', stack: '...' }
const errorString = JSON.serialize(errorObject)
const newErrorObject = JSON.parse(errorString)
const newError = parse(newErrorObject)
// Error instance: 'TypeError: example ...'
Install
npm install error-serializer
This package is an ES module and must be loaded using
an import
or import()
statement,
not require()
.
API
serialize(errorInstance, options?)
errorInstance
any
options
Options?
Return value: object
Convert an Error
instance into a plain object.
Options
Object with the following optional properties.
loose
Type: boolean
Default: false
If this option is true
and errorInstance
is not an Error
instance, it is
returned as is, instead of being converted to a plain object.
console.log(serialize('example')) // { name: 'Error', message: 'example', ... }
console.log(serialize('example', { loose: true })) // 'example'
parse(errorObject, options?)
errorObject
any
options
Options?
Return value: Error
Convert an error plain object into an Error
instance.
Options
Object with the following optional properties.
types
Type: object
Custom error types to keep when parsing.
- Each key is an
errorObject.name
. - Each value is the error type to use. The constructor will be called with a
single
message
argument. It it throws,Error
will be used as the error type instead.
const errorObject = serialize(new CustomError('example'))
// `CustomError` type is kept
const error = parse(errorObject, { types: { CustomError } })
// Map `CustomError` to another type
const otherError = parse(errorObject, { types: { CustomError: TypeError } })
loose
Type: boolean
Default: false
If this option is true
and errorObject
is not an error plain object, it is
returned as is, instead of being converted to an Error
instance.
console.log(parse('example')) // Error: example
console.log(parse('example', { loose: true })) // 'example'
Usage
JSON safety
Error plain objects are always safe to serialize with JSON.
const error = new Error('example')
error.cycle = error
// Cycles make `JSON.serialize()` throw, so they are removed
console.log(serialize(error).cycle) // {}
error.toJSON()
serialize()
can be used as
error.toJSON()
.
class CustomError extends Error {
/* constructor(...) { ... } */
toJSON() {
return serialize(this)
}
}
const error = new CustomError('example')
console.log(error.toJSON())
// { name: 'CustomError', message: 'example', stack: '...' }
console.log(JSON.stringify(error))
// '{"name":"CustomError","message":"example","stack":"..."}'
Deep serialization/parsing
Objects and arrays containing errors can be deeply serialized/parsed using the
loose
option combined with
JSON.stringify()
's replacer
and
JSON.parse()
's reviver.
const deepObject = [{}, { error: new Error('example') }]
const jsonString = JSON.stringify(deepObject, (key, value) =>
serialize(value, { loose: true }),
)
const newDeepObject = JSON.parse(jsonString, (key, value) =>
parse(value, { loose: true }),
)
console.log(newDeepObject[1].error) // Error: example
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 Error('example')
const errorObject = serialize(error)
const errorYamlString = dump(errorObject)
// name: Error
// message: example
// stack: Error: example ...
const newErrorObject = load(errorYamlString)
const newError = parse(newErrorObject) // Error: example
Additional error properties
const error = new TypeError('example')
error.prop = true
const errorObject = serialize(error)
console.log(errorObject.prop) // true
const newError = parse(errorObject)
console.log(newError.prop) // true
error.cause
and AggregateError
const innerErrors = [new Error('one'), new Error('two')]
const cause = new Error('three')
const error = new AggregateError(innerErrors, 'four', { cause })
const errorObject = serialize(error)
// {
// name: 'AggregateError',
// message: 'four',
// stack: '...',
// cause: { name: 'Error', message: 'three', stack: '...' },
// errors: [{ name: 'Error', message: 'one', stack: '...' }, ...],
// }
const newError = parse(errorObject)
// AggregateError: four
// [cause]: Error: three
// [errors]: [Error: one, Error: two]
Error normalization
Invalid error instances or objects are normalized.
// Normalizes invalid error: not an `Error` instance
console.log(serialize('example')) // { name: 'Error', message: 'example', ... }
// Normalizes `error.name`: not a string
console.log(parse({ name: false, message: 'example' })) // Error: example
Related projects
modern-errors
: Handle errors like it's 2022 🔮create-error-types
: Create multiple error typeserror-type
: Create one error typenormalize-exception
: Normalize exceptions/errorsmerge-error-cause
: Merge an error with itscause
error-cause-polyfill
: Polyfillerror.cause
handle-cli-error
: 💣 Error handler for CLI applications 💥safe-json-value
: ⛑️ JSON serialization should never faillog-process-errors
: Show some ❤ to Node.js process errors
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!