I would like to test that the following function performs as expected:
function throwNextTick(error) {
process.nextTick(function () {
throw error;
Base on timoxley & Casey Foster, in node v6++
const assert = require('assert')
describe('throwNextTick', function() {
it('works as expected', function(next) {
function cb(err) {
assert.equal(err instanceof Error, true)
next()
}
function test(){
process.nextTick(() => {
throw new Error('err')
})
}
process.prependOnceListener('uncaughtException', cb)
test()
})
})
If your async code is executed within a domain - and that is often the case - you need to change the error listener on the domain instead of the process.
For that you can use:
it('should produce an unhandled exception', function (done) {
// Remove Mocha's error listener
var originalErrorListeners = process.domain.listeners('error');
process.domain.removeAllListeners('error');
// Add your own error listener to check for unhandled exceptions
process.domain.on('error', function () {
// Add the original error listeners again
process.domain.removeAllListeners('error');
for ( var i = 0; i < originalErrorListeners.length; i+=1 ) {
process.domain.on('error', originalErrorListeners[i]);
}
// For the sake of simplicity we are done after catching the unhandled exception
done();
});
// This would be your async application code you expect to throw an exception
setTimeout(function () {
throw new Error();
});
});
Update: Courtesy of casey-foster in a comment below:
As of node v6.0.0 you can use
process.prependOnceListener('uncaughtException', ...)
to do this much more succinctly.
Old answer:
The secret lies in process.listeners('uncaughtException'):
http://nodejs.org/docs/latest/api/events.html#emitter.listeners
Simply remove the mocha listener, add your own, then reattach the mocha listener.
See below:
var assert = require('assert')
function throwNextTick(error) {
process.nextTick(function () {
throw error
})
}
describe("throwNextTick", function () {
it("works as expected", function (next) {
var error = new Error("boo!")
var recordedError = null
var originalException = process.listeners('uncaughtException').pop()
//Needed in node 0.10.5+
process.removeListener('uncaughtException', originalException);
process.once("uncaughtException", function (error) {
recordedError = error
})
throwNextTick(error);
process.nextTick(function () {
process.listeners('uncaughtException').push(originalException)
assert.equal(recordedError, error)
next()
})
})
})