diff --git a/lib/client.js b/lib/client.js index ce87f29d0a93..617b3e87a312 100644 --- a/lib/client.js +++ b/lib/client.js @@ -160,15 +160,31 @@ module.exports.patchGlobal = function patchGlobal(client, cb) { // at the end, if we still don't have a Client, let's make one! !(client instanceof Client) && (client = new Client()); + var called = false; process.on('uncaughtException', function(err) { if(cb) { // bind event listeners only if a callback was supplied - client.once('logged', function() { + var onLogged = function onLogged() { + called = false; cb(true, err); - }); - client.once('error', function() { + }; + + var onError = function onError() { + called = false; cb(false, err); - }); + }; + + if(called) { + client.removeListener('logged', onLogged); + client.removeListener('error', onError); + return cb(false, err); + } + + client.once('logged', onLogged); + client.once('error', onError); } + + called = true; + client.captureError(err, function(result) { node_util.log('uncaughtException: '+client.getIdent(result)); }); diff --git a/test/raven.client.js b/test/raven.client.js index 600b846fe1b7..d816b6ec76d2 100644 --- a/test/raven.client.js +++ b/test/raven.client.js @@ -297,6 +297,33 @@ describe('raven.Client', function(){ }); process.emit('uncaughtException', new Error('derp')); }); + + it('should not enter in recursion when an error is thrown on client request', function(done){ + // remove existing uncaughtException handlers + var uncaughtBefore = process._events.uncaughtException; + process.removeAllListeners('uncaughtException'); + + var transportBefore = client.transport.send; + + client.transport.send = function() { + throw new Error('foo'); + }; + + client.patchGlobal(function(success, err){ + success.should.eql(false); + err.should.be.instanceOf(Error); + err.message.should.equal('foo'); + + // restore things to how they were + process._events.uncaughtException = uncaughtBefore; + client.transport.send = transportBefore; + + done(); + }); + + + process.emit('uncaughtException', new Error('derp')); + }); }); describe('#process()', function(){