Skip to content

Commit 46c2ecd

Browse files
committed
Add BaseError.toJSON()
1 parent 195b248 commit 46c2ecd

File tree

8 files changed

+69
-44
lines changed

8 files changed

+69
-44
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
# 2.2.0
2+
3+
## Features
4+
5+
- `error.toJSON()` has been renamed to
6+
[`BaseError.toJSON(error)`](README.md#baseerrortojsonerror)
7+
18
# 2.1.0
29

310
## Features

README.md

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
[plugin](https://github.com/ehmicky/modern-errors#-plugins) to serialize/parse
1616
errors.
1717

18-
This adds [`error.toJSON()`](#errortojson) and
18+
This adds [`BaseError.toJSON()`](#baseerrortojsonerror) and
1919
[`BaseError.parse()`](#baseerrorparseerrorobject) to serialize/parse errors
2020
to/from plain objects.
2121

@@ -46,11 +46,11 @@ export const BaseError = ModernError.subclass('BaseError', {
4646
// ...
4747
```
4848

49-
[Serializing](#errortojson) errors to plain objects.
49+
[Serializing](#baseerrortojsonerror) errors to plain objects.
5050

5151
```js
5252
const error = new InputError('Wrong file.', { props: { filePath } })
53-
const errorObject = error.toJSON()
53+
const errorObject = BaseError.toJSON(error)
5454
// { name: 'InputError', message: 'Wrong file', stack: '...', filePath: '...' }
5555
const errorString = JSON.stringify(error)
5656
// '{"name":"InputError",...}'
@@ -88,16 +88,21 @@ Plugin object to pass to the
8888
[`plugins` option](https://github.com/ehmicky/modern-errors#adding-plugins) of
8989
`ErrorClass.subclass()`.
9090

91-
## error.toJSON()
91+
## BaseError.toJSON(error)
9292

93+
`error`: `Error`\
9394
_Return value_: `ErrorObject`
9495

9596
Converts errors to plain objects that are
9697
[serializable](https://github.com/ehmicky/error-serializer#json-safety) to JSON
9798
([or YAML](https://github.com/ehmicky/error-serializer#custom-serializationparsing),
98-
etc.). This is
99-
[automatically called](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#tojson_behavior)
100-
by `JSON.stringify()`.
99+
etc.).
100+
101+
This is also set as
102+
[`error.toJSON()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#tojson_behavior),
103+
so
104+
[`JSON.stringify()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify)
105+
automatically calls it.
101106

102107
All
103108
[error properties](https://github.com/ehmicky/error-serializer#additional-error-properties)
@@ -125,7 +130,7 @@ const error = new InputError('Wrong file.')
125130
error.cycle = error
126131

127132
// Cycles make `JSON.stringify()` throw, so they are removed
128-
console.log(error.toJSON().cycle) // undefined
133+
console.log(BaseError.toJSON(error).cycle) // undefined
129134
```
130135

131136
## Deep serialization/parsing
@@ -153,7 +158,7 @@ serialization/parsing logic to be performed.
153158
import { dump, load } from 'js-yaml'
154159

155160
const error = new InputError('Wrong file.')
156-
const errorObject = error.toJSON()
161+
const errorObject = BaseError.toJSON(error)
157162
const errorYamlString = dump(errorObject)
158163
// name: InputError
159164
// message: Wrong file.
@@ -166,7 +171,7 @@ const newError = BaseError.parse(newErrorObject) // InputError: Wrong file.
166171

167172
```js
168173
const error = new InputError('Wrong file.', { props: { prop: true } })
169-
const errorObject = error.toJSON()
174+
const errorObject = BaseError.toJSON(error)
170175
console.log(errorObject.prop) // true
171176
const newError = BaseError.parse(errorObject)
172177
console.log(newError.prop) // true
@@ -179,7 +184,7 @@ const error = new InputError('Wrong file.', {
179184
errors: [new ExampleError('one'), new ExampleError('two')],
180185
})
181186

182-
const errorObject = error.toJSON()
187+
const errorObject = BaseError.toJSON(error)
183188
// {
184189
// name: 'InputError',
185190
// message: 'Wrong file.',
@@ -212,7 +217,7 @@ const InputError = BaseError.subclass('InputError', {
212217
})
213218

214219
const error = new InputError('Wrong file.', {}, true)
215-
const errorObject = error.toJSON()
220+
const errorObject = BaseError.toJSON(error)
216221
// `constructor(message, options, prop)` is not called
217222
const newError = BaseError.parse(errorObject)
218223
// But properties set by that `constructor(...)` are kept

src/main.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { serialize, parse as parseErrorObject } from 'error-serializer'
22
import isPlainObject from 'is-plain-obj'
33

4-
// `error.toJSON()`
4+
// `ErrorClass.toJSON(error)` or `error.toJSON()`
55
const toJSON = function ({ error, instancesData }) {
66
return serialize(error, {
77
beforeSerialize: beforeSerialize.bind(undefined, instancesData),

test/helpers/main.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export const BaseError = ModernError.subclass('BaseError', {
99
export const baseError = new BaseError('message')
1010
// eslint-disable-next-line fp/no-mutation
1111
baseError.one = true
12-
export const errorObject = baseError.toJSON()
12+
export const errorObject = BaseError.toJSON(baseError)
1313

1414
export const nativeError = new TypeError('message')
1515
// eslint-disable-next-line fp/no-mutation
@@ -18,7 +18,7 @@ nativeError.one = true
1818
const parentNativeError = new BaseError('test')
1919
// eslint-disable-next-line fp/no-mutation
2020
parentNativeError.prop = nativeError
21-
export const nativeErrorObject = parentNativeError.toJSON().prop
21+
export const nativeErrorObject = BaseError.toJSON(parentNativeError).prop
2222

2323
const testPlugin = {
2424
name: 'test',
@@ -34,4 +34,6 @@ export const PluginError = BaseError.subclass('PluginError', {
3434
plugins: [testPlugin],
3535
})
3636
export const pluginError = new PluginError('message', { test: true })
37-
export const pluginErrorObject = excludeKeys(pluginError.toJSON(), ['options'])
37+
export const pluginErrorObject = excludeKeys(PluginError.toJSON(pluginError), [
38+
'options',
39+
])

test/parse.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ const InvalidError = BaseError.subclass('InvalidError', {
5656

5757
test('ErrorClass.parse() handles constructors that throw', (t) => {
5858
const invalidError = new InvalidError('message', {}, Symbol('test'))
59-
t.true(BaseError.parse(invalidError.toJSON()) instanceof BaseError)
59+
t.true(
60+
BaseError.parse(InvalidError.toJSON(invalidError)) instanceof BaseError,
61+
)
6062
})
6163

6264
test('ErrorClass.parse() keeps plugin options', (t) => {

test/serialize.js

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,47 +15,51 @@ const convertError = function ({ name, message, stack, one }) {
1515
return { name, message, stack, one }
1616
}
1717

18-
test('error.toJSON() serializes', (t) => {
18+
test('ErrorClass.toJSON() serializes', (t) => {
1919
t.deepEqual(errorObject, convertError(baseError))
2020
})
2121

2222
each([baseError, nativeError], ({ title }, deepError) => {
23-
test(`error.toJSON() is deep | ${title}`, (t) => {
23+
test(`ErrorClass.toJSON() is deep | ${title}`, (t) => {
2424
const error = new BaseError('test')
2525
error.prop = [deepError]
26-
t.deepEqual(error.toJSON().prop[0], convertError(deepError))
26+
t.deepEqual(BaseError.toJSON(error).prop[0], convertError(deepError))
2727
})
2828
})
2929

30-
test('error.toJSON() is not enumerable', (t) => {
31-
t.false(
32-
Object.getOwnPropertyDescriptor(Object.getPrototypeOf(baseError), 'toJSON')
33-
.enumerable,
34-
)
35-
})
36-
37-
test('error.toJSON() keeps plugin options', (t) => {
30+
test('ErrorClass.toJSON() keeps plugin options', (t) => {
3831
t.true(pluginErrorObject.pluginsOpts.test)
3932
})
4033

41-
test('error.toJSON() keeps plugin options deeply', (t) => {
34+
test('ErrorClass.toJSON() keeps plugin options deeply', (t) => {
4235
const error = new PluginError('message')
4336
error.cause = new PluginError('causeMessage', { test: true })
44-
t.true(error.toJSON().cause.pluginsOpts.test)
37+
t.true(PluginError.toJSON(error).cause.pluginsOpts.test)
4538
})
4639

47-
test('error.toJSON() does not keep plugin options of native errors', (t) => {
40+
test('ErrorClass.toJSON() does not keep plugin options of native errors', (t) => {
4841
const error = new PluginError('message')
4942
error.cause = new Error('causeMessage')
50-
t.false('pluginsOpts' in error.toJSON().cause)
43+
t.false('pluginsOpts' in PluginError.toJSON(error).cause)
5144
})
5245

53-
test('error.toJSON() does not keep empty plugin options', (t) => {
46+
test('ErrorClass.toJSON() does not keep empty plugin options', (t) => {
5447
const error = new PluginError('message')
55-
t.false('pluginsOpts' in error.toJSON())
48+
t.false('pluginsOpts' in PluginError.toJSON(error))
5649
})
5750

58-
test('error.toJSON() does not mutate error', (t) => {
59-
pluginError.toJSON()
51+
test('ErrorClass.toJSON() does not mutate error', (t) => {
52+
PluginError.toJSON(pluginError)
6053
t.false('pluginsOpts' in pluginError)
6154
})
55+
56+
test('error.toJSON() serializes', (t) => {
57+
t.deepEqual(baseError.toJSON(), convertError(baseError))
58+
})
59+
60+
test('error.toJSON() is not enumerable', (t) => {
61+
t.false(
62+
Object.getOwnPropertyDescriptor(Object.getPrototypeOf(baseError), 'toJSON')
63+
.enumerable,
64+
)
65+
})

types/main.d.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ export type { ErrorObject }
77
/**
88
* `modern-errors-serialize` plugin.
99
*
10-
* This plugin adds `error.toJSON()` and `BaseError.parse()` to serialize/parse
11-
* errors to plain objects.
10+
* This plugin adds `BaseError.toJSON()` and `BaseError.parse()` to
11+
* serialize/parse errors to plain objects.
1212
*/
1313
declare const plugin: {
1414
name: 'serialize'
@@ -18,9 +18,13 @@ declare const plugin: {
1818
* [serializable](https://github.com/ehmicky/error-serializer#json-safety)
1919
* to JSON
2020
* ([or YAML](https://github.com/ehmicky/error-serializer#custom-serializationparsing),
21-
* etc.). This is
22-
* [automatically called](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#tojson_behavior)
23-
* by `JSON.stringify()`.
21+
* etc.).
22+
*
23+
* This is also set as
24+
* [`error.toJSON()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#tojson_behavior),
25+
* so
26+
* [`JSON.stringify()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify)
27+
* automatically calls it.
2428
*
2529
* All
2630
* [error properties](https://github.com/ehmicky/error-serializer#additional-error-properties)
@@ -31,7 +35,7 @@ declare const plugin: {
3135
* @example
3236
* ```js
3337
* const error = new InputError('Wrong file.', { props: { filePath } })
34-
* const errorObject = error.toJSON()
38+
* const errorObject = BaseError.toJSON(error)
3539
* // { name: 'InputError', message: 'Wrong file', stack: '...', filePath: '...' }
3640
* const errorString = JSON.stringify(error)
3741
* // '{"name":"InputError",...}'

types/main.test-d.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,20 @@ const BaseError = ModernError.subclass('BaseError', {
77
plugins: [modernErrorsSerialize],
88
})
99
const error = new BaseError('')
10-
const errorObject = error.toJSON()
10+
const errorObject = BaseError.toJSON(error)
1111

1212
expectError(
1313
ModernError.subclass('TestError', {
1414
plugins: [modernErrorsSerialize],
1515
serialize: undefined,
1616
}),
1717
)
18-
expectError(error.toJSON(undefined))
18+
expectError(BaseError.toJSON(error, undefined))
1919
expectError(BaseError.parse(errorObject, undefined))
2020

2121
expectType<ErrorObject>(errorObject)
2222
expectType<string>(errorObject.name)
23+
expectType<ErrorObject>(error.toJSON())
2324

2425
expectType<unknown>(BaseError.parse(errorObject))
2526
expectType<unknown>(BaseError.parse({ errorObject }))

0 commit comments

Comments
 (0)