Skip to content

Commit adb4501

Browse files
committed
feat: Add Errors serialization to json-stringify-safe
1 parent f4d21fc commit adb4501

File tree

2 files changed

+98
-9
lines changed

2 files changed

+98
-9
lines changed

test/vendor/json-stringify-safe.test.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,67 @@ describe('Stringify', function() {
247247
assert.ok(err instanceof TypeError);
248248
});
249249

250+
it('must stringify error objects, including extra properties', function() {
251+
var obj = new Error('Wubba Lubba Dub Dub');
252+
obj.reason = new TypeError("I'm pickle Riiick!");
253+
obj.extra = 'some extra prop';
254+
255+
// Stack is inconsistent across browsers, so override it and just make sure its stringified
256+
obj.stack = 'x';
257+
obj.reason.stack = 'x';
258+
259+
// IE 10/11
260+
delete obj.description;
261+
delete obj.reason.description;
262+
263+
// Safari doesn't allow deleting those properties from error object, yet only it provides them
264+
var result = stringify(obj, null, 2)
265+
.replace(/ +"(line|column|sourceURL)": .+,?\n/g, '')
266+
.replace(/,\n( +)}/g, '\n$1}'); // make sure to strip trailing commas as well
267+
268+
assert.equal(
269+
result,
270+
jsonify({
271+
stack: 'x',
272+
message: 'Wubba Lubba Dub Dub',
273+
name: 'Error',
274+
reason: {
275+
stack: 'x',
276+
message: "I'm pickle Riiick!",
277+
name: 'TypeError'
278+
},
279+
extra: 'some extra prop'
280+
})
281+
);
282+
});
283+
284+
it('must stringify error objects with circular references', function() {
285+
var obj = new Error('Wubba Lubba Dub Dub');
286+
obj.reason = obj;
287+
288+
// Stack is inconsistent across browsers, so override it and just make sure its stringified
289+
obj.stack = 'x';
290+
obj.reason.stack = 'x';
291+
292+
// IE 10/11
293+
delete obj.description;
294+
295+
// Safari doesn't allow deleting those properties from error object, yet only it provides them
296+
var result = stringify(obj, null, 2)
297+
.replace(/ +"(line|column|sourceURL)": .+,?\n/g, '')
298+
.replace(/,\n( +)}/g, '\n$1}'); // make sure to strip trailing commas as well
299+
300+
assert.equal(
301+
result,
302+
jsonify({
303+
stack: 'x',
304+
message: 'Wubba Lubba Dub Dub',
305+
name: 'Error',
306+
reason: '[Circular ~]'
307+
})
308+
);
309+
});
310+
250311
describe('.getSerialize', function() {
251312
it('must stringify circular objects', function() {
252313
var obj = {a: 'b'};

vendor/json-stringify-safe/stringify.js

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
Like JSON.stringify, but doesn't throw on circular references.
44
55
Originally forked from https://github.com/isaacs/json-stringify-safe
6-
version 5.0.1 on 3/8/2017 and modified for IE8 compatibility.
7-
Tests for this are in test/vendor.
6+
version 5.0.1 on 3/8/2017 and modified to handle Errors serialization
7+
and IE8 compatibility. Tests for this are in test/vendor.
88
99
ISC license: https://github.com/isaacs/json-stringify-safe/blob/master/LICENSE
1010
*/
@@ -23,24 +23,52 @@ function stringify(obj, replacer, spaces, cycleReplacer) {
2323
return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces);
2424
}
2525

26+
// https://github.com/ftlabs/js-abbreviate/blob/fa709e5f139e7770a71827b1893f22418097fbda/index.js#L95-L106
27+
function stringifyError(value) {
28+
var err = {
29+
// These properties are implemented as magical getters and don't show up in for in
30+
stack: value.stack,
31+
message: value.message,
32+
name: value.name
33+
};
34+
35+
for (var i in value) {
36+
if (Object.prototype.hasOwnProperty.call(value, i)) {
37+
err[i] = value[i];
38+
}
39+
}
40+
41+
return err;
42+
}
43+
2644
function serializer(replacer, cycleReplacer) {
27-
var stack = [],
28-
keys = [];
45+
var stack = [];
46+
var keys = [];
2947

30-
if (cycleReplacer == null)
48+
if (cycleReplacer == null) {
3149
cycleReplacer = function(key, value) {
32-
if (stack[0] === value) return '[Circular ~]';
50+
if (stack[0] === value) {
51+
return '[Circular ~]';
52+
}
3353
return '[Circular ~.' + keys.slice(0, indexOf(stack, value)).join('.') + ']';
3454
};
55+
}
3556

3657
return function(key, value) {
3758
if (stack.length > 0) {
3859
var thisPos = indexOf(stack, this);
3960
~thisPos ? stack.splice(thisPos + 1) : stack.push(this);
4061
~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key);
41-
if (~indexOf(stack, value)) value = cycleReplacer.call(this, key, value);
42-
} else stack.push(value);
4362

44-
return replacer == null ? value : replacer.call(this, key, value);
63+
if (~indexOf(stack, value)) {
64+
value = cycleReplacer.call(this, key, value);
65+
}
66+
} else {
67+
stack.push(value);
68+
}
69+
70+
return replacer == null
71+
? value instanceof Error ? stringifyError(value) : value
72+
: replacer.call(this, key, value);
4573
};
4674
}

0 commit comments

Comments
 (0)