Skip to content

Commit 0e47a7d

Browse files
committed
Adapt stackWithCauses() to node.js output
Fixes #22 Related to: staltz/clarify-error#1 and nodejs/node#41002
1 parent 90a012f commit 0e47a7d

File tree

2 files changed

+65
-2
lines changed

2 files changed

+65
-2
lines changed

index.js

+15-2
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,24 @@ const _stackWithCauses = (err, seen) => {
103103

104104
const cause = getErrorCause(err);
105105

106-
// TODO: Follow up in https://github.com/nodejs/node/issues/38725#issuecomment-920309092 on how to log stuff
107-
108106
if (cause) {
109107
seen.add(err);
110108
return (stack + '\ncaused by: ' + _stackWithCauses(cause, seen));
109+
} else if (
110+
// @ts-ignore
111+
Object.prototype.hasOwnProperty.call(err, 'cause')
112+
) {
113+
/** @type {string} */
114+
let stringified;
115+
try {
116+
stringified = JSON.stringify(
117+
// @ts-ignore
118+
err.cause
119+
);
120+
} catch {
121+
stringified = '<failed to stringify value>';
122+
}
123+
return (stack + '\ncaused by: ' + stringified);
111124
} else {
112125
return stack;
113126
}

test/stack.spec.js

+50
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,54 @@ describe('stackWithCauses()', () => {
9292
const result = stackWithCauses(err);
9393
result.should.equal('xyz789\ncaused by: abc123\ncaused by: xyz789\ncauses have become circular...');
9494
});
95+
96+
describe('should append non-Error causes to the end of the cause trail', () => {
97+
it('for string causes', () => {
98+
const err = new ErrorWithCause('foo', { cause: 'string cause' });
99+
err.stack = 'xyz789';
100+
stackWithCauses(err).should.equal('xyz789\ncaused by: "string cause"');
101+
});
102+
103+
it('for number causes', () => {
104+
const err = new ErrorWithCause('foo', { cause: 123 });
105+
err.stack = 'xyz789';
106+
stackWithCauses(err).should.equal('xyz789\ncaused by: 123');
107+
});
108+
109+
it('for non-Error object causes', () => {
110+
const err = new ErrorWithCause('foo', { cause: { name: 'TypeError', message: 'foo' } });
111+
err.stack = 'xyz789';
112+
stackWithCauses(err).should.equal('xyz789\ncaused by: {"name":"TypeError","message":"foo"}');
113+
});
114+
115+
it('should not throw for circular non-Error object causes', () => {
116+
const firstCause = { first: true };
117+
const secondCause = { second: true, firstCause };
118+
119+
// @ts-ignore
120+
firstCause.secondCause = secondCause;
121+
122+
const err = new ErrorWithCause('foo', { cause: firstCause });
123+
err.stack = 'xyz789';
124+
stackWithCauses(err).should.equal('xyz789\ncaused by: <failed to stringify value>');
125+
});
126+
127+
// Copied from https://github.com/nodejs/node/blob/5e6f9c3e346b196ab299a3fce485d7aa5fbf3802/test/parallel/test-util-inspect.js#L663-L677
128+
it('for falsy causes', () => {
129+
const falsyCause1 = new ErrorWithCause('', { cause: false });
130+
delete falsyCause1.stack;
131+
132+
// @ts-ignore
133+
// eslint-disable-next-line unicorn/no-null
134+
const falsyCause2 = new ErrorWithCause(undefined, { cause: null });
135+
falsyCause2.stack = '';
136+
137+
const undefinedCause = new ErrorWithCause('', { cause: undefined });
138+
undefinedCause.stack = '';
139+
140+
stackWithCauses(falsyCause1).should.equal('\ncaused by: false');
141+
stackWithCauses(falsyCause2).should.equal('\ncaused by: null');
142+
stackWithCauses(undefinedCause).should.equal('\ncaused by: undefined');
143+
});
144+
});
95145
});

0 commit comments

Comments
 (0)