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.
This commit is contained in:
Benjamin Thomas 2010-08-27 02:50:12 -06:00 коммит произвёл Ryan Dahl
Родитель 4fdebab005
Коммит 57642e2349
2 изменённых файлов: 51 добавлений и 2 удалений

Просмотреть файл

@ -49,9 +49,17 @@ var nextTickQueue = [];
process._tickCallback = function () {
var l = nextTickQueue.length;
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);
};

Просмотреть файл

@ -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);
});