diff --git a/lib/runner.js b/lib/runner.js index 6aefb34cce..bfc58b3ecd 100644 --- a/lib/runner.js +++ b/lib/runner.js @@ -703,15 +703,18 @@ Runner.prototype.runSuite = function(suite, fn) { }; /** - * Handle uncaught exceptions. + * Handle uncaught exceptions and unhandled rejections. * * @param {Error} err + * @param {boolean|undefined} unhandled - true for unhandled rejections. * @api private */ -Runner.prototype.uncaught = function(err) { +Runner.prototype.uncaught = function(err, unhandled) { + var type = unhandled ? 'unhanled' : 'uncaught'; if (err) { debug( - 'uncaught exception %s', + '%s exception %s', + type, err === function() { return this; @@ -723,12 +726,13 @@ Runner.prototype.uncaught = function(err) { debug('uncaught undefined exception'); err = undefinedError(); } - err.uncaught = true; + err[type] = true; var runnable = this.currentRunnable; if (!runnable) { - runnable = new Runnable('Uncaught error outside test suite'); + var capitalized = unhandled ? 'Unhandled' : 'Uncaught'; + runnable = new Runnable(capitalized + ' error outside test suite'); runnable.parent = this.suite; if (this.started) { @@ -839,6 +843,10 @@ Runner.prototype.run = function(fn) { self.uncaught(err); } + function unhandled(reason, promise) { + self.uncaught(reason, true); + } + function start() { // If there is an `only` filter if (hasOnly(rootSuite)) { @@ -861,11 +869,14 @@ Runner.prototype.run = function(fn) { this.on('end', function() { debug('end'); process.removeListener('uncaughtException', uncaught); + process.removeListener('unhandledRejection', unhandled); fn(self.failures); }); // uncaught exception process.on('uncaughtException', uncaught); + // unhandled rejections + process.on('unhandledRejection', unhandled); if (this._delay) { // for reporters, I guess.