Skip to content

Commit

Permalink
Adapt stackWithCauses() to node.js output
Browse files Browse the repository at this point in the history
  • Loading branch information
voxpelli committed May 31, 2022
1 parent 90a012f commit d1c1fbc
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 2 deletions.
12 changes: 10 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,19 @@ const _stackWithCauses = (err, seen) => {

const cause = getErrorCause(err);

// TODO: Follow up in https://github.com/nodejs/node/issues/38725#issuecomment-920309092 on how to log stuff

if (cause) {
seen.add(err);
return (stack + '\ncaused by: ' + _stackWithCauses(cause, seen));
} else if (Object.prototype.hasOwnProperty.call(err, 'cause')) {
/** @type {string} */
let stringified;
try {
// @ts-ignore
stringified = JSON.stringify(err.cause);
} catch {
stringified = '<failed to stringify value>';
}
return (stack + '\ncaused by: ' + stringified);
} else {
return stack;
}
Expand Down
50 changes: 50 additions & 0 deletions test/stack.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,54 @@ describe('stackWithCauses()', () => {
const result = stackWithCauses(err);
result.should.equal('xyz789\ncaused by: abc123\ncaused by: xyz789\ncauses have become circular...');
});

describe('should append non-Error causes to the end of the cause trail', () => {
it('for string causes', () => {
const err = new ErrorWithCause('foo', { cause: 'string cause' });
err.stack = 'xyz789';
stackWithCauses(err).should.equal('xyz789\ncaused by: "string cause"');
});

it('for number causes', () => {
const err = new ErrorWithCause('foo', { cause: 123 });
err.stack = 'xyz789';
stackWithCauses(err).should.equal('xyz789\ncaused by: 123');
});

it('for non-Error object causes', () => {
const err = new ErrorWithCause('foo', { cause: { name: 'TypeError', message: 'foo' } });
err.stack = 'xyz789';
stackWithCauses(err).should.equal('xyz789\ncaused by: {"name":"TypeError","message":"foo"}');
});

it('should not throw for circular non-Error object causes', () => {
const firstCause = { first: true };
const secondCause = { second: true, firstCause };

// @ts-ignore
firstCause.secondCause = secondCause;

const err = new ErrorWithCause('foo', { cause: firstCause });
err.stack = 'xyz789';
stackWithCauses(err).should.equal('xyz789\ncaused by: <failed to stringify value>');
});

// Copied from https://github.com/nodejs/node/blob/5e6f9c3e346b196ab299a3fce485d7aa5fbf3802/test/parallel/test-util-inspect.js#L663-L677
it('for falsy causes', () => {
const falsyCause1 = new ErrorWithCause('', { cause: false });
delete falsyCause1.stack;

// @ts-ignore
// eslint-disable-next-line unicorn/no-null
const falsyCause2 = new ErrorWithCause(undefined, { cause: null });
falsyCause2.stack = '';

const undefinedCause = new ErrorWithCause('', { cause: undefined });
undefinedCause.stack = '';

stackWithCauses(falsyCause1).should.equal('\ncaused by: false');
stackWithCauses(falsyCause2).should.equal('\ncaused by: null');
stackWithCauses(undefinedCause).should.equal('\ncaused by: undefined');
});
});
});

0 comments on commit d1c1fbc

Please sign in to comment.