Skip to content

Commit ae83956

Browse files
authored
Serialize errors with cause (#105)
* Add (failing) test for serialization of causes of errors * Add cause serialization to error serializer The error serializer already handles the case where an error is not of type Error (or AggregateError) well, so there is no reason to add special handling for that. We can simply pass whatever is in `cause` into the serializer, and we should get a serialized result out. * Add `cause` to errors in similar way to what is done in other errors * Expand cause serialization test to show recursion
1 parent c40269b commit ae83956

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

lib/err.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ const pinoErrProto = Object.create({}, {
2828
writable: true,
2929
value: undefined
3030
},
31+
cause: {
32+
enumerable: true,
33+
writable: true,
34+
value: undefined
35+
},
3136
raw: {
3237
enumerable: false,
3338
get: function () {
@@ -60,6 +65,10 @@ function errSerializer (err) {
6065
_err.aggregateErrors = err.errors.map(err => errSerializer(err))
6166
}
6267

68+
if (err.cause) {
69+
_err.cause = errSerializer(err.cause)
70+
}
71+
6372
for (const key in err) {
6473
if (_err[key] === undefined) {
6574
const val = err[key]

test/err.test.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,27 @@ test('serializes aggregate errors', { skip: !global.AggregateError }, function (
194194
t.match(serialized.aggregateErrors[1].stack, /^Error: bar/)
195195
t.match(serialized.stack, /err\.test\.js:/)
196196
})
197+
198+
test('serializes causes', function (t) {
199+
t.plan(11)
200+
201+
const bar = new Error('bar')
202+
bar.cause = new Error('foo')
203+
bar.cause.cause = new Error('baz')
204+
205+
const serialized = serializer(bar)
206+
207+
t.equal(serialized.type, 'Error')
208+
t.equal(serialized.message, 'bar: foo: baz') // message serialization already walks cause-chain
209+
t.match(serialized.stack, /err\.test\.js:/)
210+
211+
t.ok(serialized.cause)
212+
t.equal(serialized.cause.type, 'Error')
213+
t.equal(serialized.cause.message, 'foo: baz')
214+
t.match(serialized.cause.stack, /err\.test\.js:/)
215+
216+
t.ok(serialized.cause.cause)
217+
t.equal(serialized.cause.cause.type, 'Error')
218+
t.equal(serialized.cause.cause.message, 'baz')
219+
t.match(serialized.cause.cause.stack, /err\.test\.js:/)
220+
})

0 commit comments

Comments
 (0)