Skip to content

Commit 31082d7

Browse files
authored
feat: support error cause (#1012)
1 parent a496f0a commit 31082d7

File tree

5 files changed

+100
-6
lines changed

5 files changed

+100
-6
lines changed

src/browser/transforms.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ function addErrorContext(item) {
4242

4343
chain.push(err);
4444

45-
while (err.nested) {
46-
err = err.nested;
45+
while (err.nested || err.cause) {
46+
err = err.nested || err.cause;
4747
chain.push(err);
4848
}
4949

src/errorParser.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,11 @@ function Stack(exception, skip) {
6464
function parse(e, skip) {
6565
var err = e;
6666

67-
if (err.nested) {
67+
if (err.nested || err.cause) {
6868
var traceChain = [];
6969
while (err) {
7070
traceChain.push(new Stack(err, skip));
71-
err = err.nested;
71+
err = err.nested || err.cause;
7272

7373
skip = 0; // Only apply skip value to primary error
7474
}

src/server/transforms.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ function handleItemWithError(item, options, callback) {
8585
var chain = [];
8686
do {
8787
errors.push(err);
88-
err = err.nested;
88+
err = err.nested || err.cause;
8989
} while (err);
9090
item.stackInfo = chain;
9191

test/browser.transforms.test.js

+43
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ function itemFromArgs(args) {
3030
return item;
3131
}
3232

33+
function chromeMajorVersion() {
34+
return parseInt(navigator.userAgent.match(/Chrome\/([0-9]+)\./)[1]);
35+
}
36+
3337
describe('handleDomException', function() {
3438
it('should do nothing if not a DOMException', function(done) {
3539
var err = new Error('test');
@@ -452,6 +456,45 @@ describe('addBody', function() {
452456
});
453457
});
454458
});
459+
describe('with error cause', function() {
460+
// Error cause was introduced in Chrome 93.
461+
if (chromeMajorVersion() < 93) return;
462+
463+
it('should create trace_chain', function(done) {
464+
var causeErr = new Error('cause error');
465+
var err = new Error('test error', { cause: causeErr});
466+
var args = ['a message', err];
467+
var item = itemFromArgs(args);
468+
var options = {};
469+
t.handleItemWithError(item, options, function(e, i) {
470+
expect(i.stackInfo).to.be.ok();
471+
});
472+
t.addBody(item, options, function(e, i) {
473+
expect(i.data.body.trace_chain.length).to.eql(2);
474+
expect(i.data.body.trace_chain[0].exception.message).to.eql('test error');
475+
expect(i.data.body.trace_chain[1].exception.message).to.eql('cause error');
476+
done(e);
477+
});
478+
});
479+
it('should create add error context as custom data', function(done) {
480+
var causeErr = new Error('cause error');
481+
causeErr.rollbarContext = { err1: 'cause context' };
482+
var err = new Error('test error', { cause: causeErr});
483+
err.rollbarContext = { err2: 'error context' };
484+
var args = ['a message', err];
485+
var item = itemFromArgs(args);
486+
var options = { addErrorContext: true };
487+
t.handleItemWithError(item, options, function(e, i) {
488+
expect(i.stackInfo).to.be.ok();
489+
});
490+
t.addBody(item, options, function(e, i) {
491+
expect(i.data.body.trace_chain.length).to.eql(2);
492+
expect(i.data.custom.err1).to.eql('cause context');
493+
expect(i.data.custom.err2).to.eql('error context');
494+
done(e);
495+
});
496+
});
497+
});
455498
});
456499

457500
describe('scrubPayload', function() {

test/server.transforms.test.js

+52-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,22 @@ async function throwInScriptFile(rollbar, filepath, callback) {
3030
callback(rollbar);
3131
}
3232

33+
var nodeVersion = function () {
34+
var version = process.versions.node.split('.');
35+
36+
return [
37+
parseInt(version[0]),
38+
parseInt(version[1]),
39+
parseInt(version[2]),
40+
];
41+
}();
42+
43+
var isMinNodeVersion = function(major, minor) {
44+
return (
45+
nodeVersion[0] > major || (nodeVersion[0] === major && nodeVersion[1] >= minor)
46+
);
47+
}
48+
3349
vows.describe('transforms')
3450
.addBatch({
3551
'baseData': {
@@ -494,7 +510,42 @@ vows.describe('transforms')
494510
assert.equal(item.data.custom.err1, 'nested context');
495511
assert.equal(item.data.custom.err2, 'error context');
496512
}
497-
}
513+
},
514+
'with an error cause': {
515+
topic: function (options) {
516+
var test = function() {
517+
var x = thisVariableIsNotDefined;
518+
};
519+
var err;
520+
try {
521+
test();
522+
} catch (e) {
523+
err = new Error('cause message', { cause: e });
524+
e.rollbarContext = { err1: 'cause context' };
525+
err.rollbarContext = { err2: 'error context' };
526+
}
527+
var item = {
528+
data: {body: {}},
529+
err: err
530+
};
531+
t.handleItemWithError(item, options, this.callback);
532+
},
533+
'should not error': function(err, item) {
534+
assert.ifError(err);
535+
},
536+
'should have the right data in the trace_chain': function(err, item) {
537+
// Error cause was introduced in Node 16.9.
538+
if (!isMinNodeVersion(16, 9)) return;
539+
540+
var trace_chain = item.stackInfo;
541+
assert.lengthOf(trace_chain, 2);
542+
assert.equal(trace_chain[0].exception.class, 'Error');
543+
assert.equal(trace_chain[0].exception.message, 'cause message');
544+
assert.equal(trace_chain[1].exception.class, 'ReferenceError');
545+
assert.equal(item.data.custom.err1, 'cause context');
546+
assert.equal(item.data.custom.err2, 'error context');
547+
}
548+
},
498549
}
499550
}
500551
}

0 commit comments

Comments
 (0)