From 0dbf25c8760ceda37e83c6f6e5319739a436c470 Mon Sep 17 00:00:00 2001 From: Ali Ijaz Sheikh Date: Wed, 20 Apr 2016 09:28:01 -0700 Subject: [PATCH] defer breakpoint callback Make sure the breakpoint hit callback isn't called back from the debug listener, which swallows user exceptions thrown from the callback. --- lib/v8debugapi.js | 7 ++++++- test/test-v8debugapi.js | 27 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/lib/v8debugapi.js b/lib/v8debugapi.js index 5de7c181..342d4847 100644 --- a/lib/v8debugapi.js +++ b/lib/v8debugapi.js @@ -196,7 +196,12 @@ module.exports.create = function(logger_, config_, fileStats_) { var listener = onBreakpointHit.bind( null, breakpoint, function(err) { delete listeners[num]; - callback(err); + // This method is called from the debug event listener, which + // swallows all exception. We defer the callback to make sure the + // user errors aren't silenced. + setImmediate(function() { + callback(err); + }); }); listeners[num] = listener; diff --git a/test/test-v8debugapi.js b/test/test-v8debugapi.js index 6e6194f5..be3b3aa0 100644 --- a/test/test-v8debugapi.js +++ b/test/test-v8debugapi.js @@ -700,6 +700,33 @@ describe('v8debugapi', function() { process.nextTick(function() {foo();}); }); }); + + it('should not silence errors thrown in the wait callback', function(done) { + var message = 'This exception should not be silenced'; + // Remove the mocha listener. + var listeners = process.listeners('uncaughtException'); + assert.equal(listeners.length, 1); + var originalListener = listeners[0]; + process.removeListener('uncaughtException', originalListener); + process.once('uncaughtException', function(err) { + assert.ok(err); + assert.equal(err.message, message); + // Restore the mocha listener. + process.on('uncaughtException', originalListener); + done(); + }); + + // clone a clean breakpointInFoo + var bp = {id: breakpointInFoo.id, location: breakpointInFoo.location}; + api.set(bp, function(err) { + assert.ifError(err); + api.wait(bp, function(err) { + api.clear(bp); + throw new Error(message); + }); + process.nextTick(function() {foo(1);}); + }); + }); }); it('should be possible to set deferred breakpoints');