Skip to content

Commit

Permalink
Fix leaking global 'uncaughtException' handler (#4147)
Browse files Browse the repository at this point in the history
  • Loading branch information
juergba authored Jan 11, 2020
1 parent 7d78f20 commit 0e1ccbb
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 7 deletions.
21 changes: 14 additions & 7 deletions lib/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,7 @@ Runner.prototype.runSuite = function(suite, fn) {
};

/**
* Handle uncaught exceptions.
* Handle uncaught exceptions within runner.
*
* @param {Error} err
* @private
Expand Down Expand Up @@ -893,6 +893,17 @@ Runner.prototype.uncaught = function(err) {
this.abort();
};

/**
* Handle uncaught exceptions after runner's end event.
*
* @param {Error} err
* @private
*/
Runner.prototype.uncaughtEnd = function uncaughtEnd(err) {
if (err instanceof Pending) return;
throw err;
};

/**
* Run the root suite and invoke `fn(failures)`
* on completion.
Expand Down Expand Up @@ -940,16 +951,12 @@ Runner.prototype.run = function(fn) {
this.on(constants.EVENT_RUN_END, function() {
debug(constants.EVENT_RUN_END);
process.removeListener('uncaughtException', uncaught);
process.on('uncaughtException', function(err) {
if (err instanceof Pending) {
return;
}
throw err;
});
process.on('uncaughtException', self.uncaughtEnd);
fn(self.failures);
});

// uncaught exception
process.removeListener('uncaughtException', self.uncaughtEnd);
process.on('uncaughtException', uncaught);

if (this._delay) {
Expand Down
12 changes: 12 additions & 0 deletions test/integration/fixtures/uncaught/listeners.fixture.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use strict';

const assert = require('assert');
const mocha = require("../../../../lib/mocha");

for (let i = 0; i < 15; i++) {
const r = new mocha.Runner(new mocha.Suite("" + i, undefined));
r.run();
}

assert.equal(process.listenerCount('uncaughtException'), 1);
assert.equal(process.listeners('uncaughtException')[0].name, 'uncaughtEnd');
12 changes: 12 additions & 0 deletions test/integration/uncaught.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,16 @@ describe('uncaught exceptions', function() {
done();
});
});

it('removes uncaught exceptions handlers correctly', function(done) {
run('uncaught/listeners.fixture.js', args, function(err, res) {
if (err) {
return done(err);
}

expect(res, 'to have passed').and('to have passed test count', 0);

done();
});
});
});

0 comments on commit 0e1ccbb

Please sign in to comment.