diff --git a/browser-entry.js b/browser-entry.js index fd89117755..148af07012 100644 --- a/browser-entry.js +++ b/browser-entry.js @@ -58,8 +58,8 @@ process.removeListener = function(e, fn) { process.on = function(e, fn) { if (e === 'uncaughtException') { - global.onerror = function(err, url, line) { - fn(new Error(err + ' (' + url + ':' + line + ')')); + global.onerror = function(msg, url, line, col, err) { + fn(err || new Error(msg + ' (' + url + ':' + line + ')')); return !mocha.allowUncaught; }; uncaughtExceptionHandlers.push(fn); diff --git a/test/unit/throw.spec.js b/test/unit/throw.spec.js index 2dc3c8a759..f7d14c070b 100644 --- a/test/unit/throw.spec.js +++ b/test/unit/throw.spec.js @@ -2,6 +2,7 @@ /* eslint no-throw-literal: off */ +var sinon = require('sinon'); var Mocha = require('../../lib/mocha'); var Suite = Mocha.Suite; var Test = Mocha.Test; @@ -13,11 +14,13 @@ var STATE_FAILED = Runnable.constants.STATE_FAILED; describe('a test that throws', function() { var suite; var runner; + var sandbox; var uncaughtHandlers; beforeEach(function() { suite = new Suite('Suite', 'root'); runner = new Runner(suite); + sandbox = sinon.createSandbox(); // see https://github.com/mochajs/mocha/pull/2983#issuecomment-350428522 uncaughtHandlers = process.listeners('uncaughtException') || []; @@ -169,4 +172,35 @@ describe('a test that throws', function() { runner.run(); }); }); + + describe('stack', function() { + it('should include the stack when throwing async', function(done) { + var test = new Test('im async and throw null async', function(done2) { + process.nextTick(function throwError() { + throw new Error('test error'); + }); + }); + suite.addTest(test); + runner = new Runner(suite); + sandbox.stub(runner, 'fail'); + + runner.on(EVENT_RUN_END, function() { + try { + expect(runner.fail, 'to have all calls satisfying', [ + expect.it('to be a', Runnable), + expect.it('to be an', Error).and('to satisfy', { + message: /test error/i, + stack: /throwError/i, + uncaught: true + }) + ]).and('was called once'); + } catch (err) { + return done(err); + } + + done(); + }); + runner.run(); + }); + }); });