Browse Source

Fix process.nextTick so thrown errors don't confuse it.

If the function for a process.nextTick throws an error, then the
splice() never removes that function from the nextTickQueue array.  This
makes sure the functions that have been run in _tickCallback get removed
regardless of errors.

Also add a test for this.
v0.7.4-release
Benjamin Thomas 15 years ago
committed by Ryan Dahl
parent
commit
57642e2349
  1. 12
      src/node.js
  2. 41
      test/simple/test-next-tick-errors.js

12
src/node.js

@ -49,9 +49,17 @@ var nextTickQueue = [];
process._tickCallback = function () { process._tickCallback = function () {
var l = nextTickQueue.length; var l = nextTickQueue.length;
if (l === 0) return; if (l === 0) return;
for (var i = 0; i < l; i++) {
nextTickQueue[i](); try {
for (var i = 0; i < l; i++) {
nextTickQueue[i]();
}
} }
catch(e) {
nextTickQueue.splice(0, i+1);
throw e;
}
nextTickQueue.splice(0, l); nextTickQueue.splice(0, l);
}; };

41
test/simple/test-next-tick-errors.js

@ -0,0 +1,41 @@
common = require("../common");
assert = common.assert
var order = [],
exceptionHandled = false;
// This nextTick function will throw an error. It should only be called once.
// When it throws an error, it should still get removed from the queue.
process.nextTick(function() {
order.push('A');
// cause an error
what();
});
// This nextTick function should remain in the queue when the first one
// is removed.
process.nextTick(function() {
order.push('C');
});
process.addListener('uncaughtException', function() {
if (!exceptionHandled) {
exceptionHandled = true;
order.push('B');
// We call process.nextTick here to make sure the nextTick queue is
// processed again. If everything goes according to plan then when the queue
// gets ran there will be two functions with this being the second.
process.nextTick(function() {
order.push('D');
});
}
else {
// If we get here then the first process.nextTick got called twice
order.push('OOPS!');
}
});
process.addListener('exit', function() {
assert.deepEqual(['A','B','C','D'], order);
});
Loading…
Cancel
Save