Skip to content

Commit b54fdf2

Browse files
urishkamilogorek
authored andcommitted
fix: preserve context in for rejected promises (#428)
currently, context is lost in case of an unhandled promise rejection. This fix keeps track of the context by looking into the rejected promise domain. This fix has been tested in my production environment and seems to do the trick there.
1 parent 339d21f commit b54fdf2

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed

lib/client.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,9 @@ extend(Raven.prototype, {
120120

121121
if (this.captureUnhandledRejections) {
122122
var self = this;
123-
global.process.on('unhandledRejection', function(reason) {
124-
self.captureException(reason, function(sendErr, eventId) {
123+
global.process.on('unhandledRejection', function(reason, promise) {
124+
var context = promise.domain && promise.domain.sentryContext;
125+
self.captureException(reason, context || {}, function(sendErr, eventId) {
125126
if (!sendErr) utils.consoleAlert('unhandledRejection captured: ' + eventId);
126127
});
127128
});

test/raven.client.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,59 @@ describe('raven.Client', function() {
427427
}
428428
});
429429

430+
it('should preserve context on unhandledRejection', function(done) {
431+
var listeners = process.listeners('unhandledRejection');
432+
listeners.length.should.equal(0);
433+
434+
var scope = nock('https://app.getsentry.com')
435+
.filteringRequestBody(/.*/, '*')
436+
.post('/api/269/store/', '*')
437+
.reply(200, function(uri, body) {
438+
zlib.inflate(new Buffer(body, 'base64'), function(err, dec) {
439+
if (err) return done(err);
440+
var msg = JSON.parse(dec.toString());
441+
442+
msg.user.should.eql({
443+
id: '123'
444+
});
445+
446+
scope.done();
447+
done();
448+
});
449+
return 'OK';
450+
});
451+
452+
client = new raven.Client(dsn, {captureUnhandledRejections: true});
453+
client.install();
454+
455+
listeners = process.listeners('unhandledRejection');
456+
listeners.length.should.equal(1);
457+
458+
client.context(function() {
459+
client.setContext({
460+
user: {
461+
id: '123'
462+
}
463+
});
464+
465+
// promises didn't include domain property until 8.0.0
466+
// see: https://nodejs.org/api/domain.html#domain_domains_and_promises
467+
// also: https://github.com/nodejs/node/pull/12489
468+
if (process.version >= 'v8.0.0') {
469+
// eslint-disable-next-line no-new
470+
new Promise(function(resolve, reject) {
471+
reject(new Error('rejected!'));
472+
});
473+
} else {
474+
setTimeout(function() {
475+
var error = new Error('rejected!');
476+
var promise = Promise.reject(error);
477+
process.emit('unhandledRejection', error, promise);
478+
});
479+
}
480+
});
481+
});
482+
430483
it('should add itself to the uncaughtException event list', function() {
431484
var listeners = process.listeners('uncaughtException');
432485
listeners.length.should.equal(0);

0 commit comments

Comments
 (0)