Fix process.nextTick throw call sites
This patch now reports the proper throw call site for exceptions triggered within process.nextTick. So instead of this: node.js:201 throw e; // process.nextTick error, or 'error' event on first tick ^ You will now see: mydir/myscript.js:15 throw new Error('My Error'); ^ From my testing this patch causes no performance regressions, but does greatly simplify processing the nextTickQueue.
This commit is contained in:
parent
ee437c0557
commit
814033365b
12
src/node.cc
12
src/node.cc
@ -255,9 +255,7 @@ static void Spin(uv_idle_t* handle, int status) {
|
|||||||
Tick();
|
Tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void StartTickSpinner() {
|
||||||
static Handle<Value> NeedTickCallback(const Arguments& args) {
|
|
||||||
HandleScope scope;
|
|
||||||
need_tick_cb = true;
|
need_tick_cb = true;
|
||||||
// TODO: this tick_spinner shouldn't be necessary. An ev_prepare should be
|
// TODO: this tick_spinner shouldn't be necessary. An ev_prepare should be
|
||||||
// sufficent, the problem is only in the case of the very last "tick" -
|
// sufficent, the problem is only in the case of the very last "tick" -
|
||||||
@ -268,9 +266,12 @@ static Handle<Value> NeedTickCallback(const Arguments& args) {
|
|||||||
uv_idle_start(&tick_spinner, Spin);
|
uv_idle_start(&tick_spinner, Spin);
|
||||||
uv_ref(uv_default_loop());
|
uv_ref(uv_default_loop());
|
||||||
}
|
}
|
||||||
return Undefined();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Handle<Value> NeedTickCallback(const Arguments& args) {
|
||||||
|
StartTickSpinner();
|
||||||
|
return Undefined();
|
||||||
|
}
|
||||||
|
|
||||||
static void PrepareTick(uv_prepare_t* handle, int status) {
|
static void PrepareTick(uv_prepare_t* handle, int status) {
|
||||||
assert(handle == &prepare_tick_watcher);
|
assert(handle == &prepare_tick_watcher);
|
||||||
@ -1694,6 +1695,9 @@ void FatalException(TryCatch &try_catch) {
|
|||||||
emit->Call(process, 2, event_argv);
|
emit->Call(process, 2, event_argv);
|
||||||
// Decrement so we know if the next exception is a recursion or not
|
// Decrement so we know if the next exception is a recursion or not
|
||||||
uncaught_exception_counter--;
|
uncaught_exception_counter--;
|
||||||
|
|
||||||
|
// This makes sure uncaught exceptions don't interfere with process.nextTick
|
||||||
|
StartTickSpinner();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
24
src/node.js
24
src/node.js
@ -180,26 +180,18 @@
|
|||||||
|
|
||||||
startup.processNextTick = function() {
|
startup.processNextTick = function() {
|
||||||
var nextTickQueue = [];
|
var nextTickQueue = [];
|
||||||
|
var nextTickIndex = 0;
|
||||||
|
|
||||||
process._tickCallback = function() {
|
process._tickCallback = function() {
|
||||||
var l = nextTickQueue.length;
|
var nextTickLength = nextTickQueue.length;
|
||||||
if (l === 0) return;
|
if (nextTickLength === 0) return;
|
||||||
|
|
||||||
var q = nextTickQueue;
|
while (nextTickIndex < nextTickLength) {
|
||||||
nextTickQueue = [];
|
nextTickQueue[nextTickIndex++]();
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
nextTickQueue.splice(0, nextTickIndex);
|
||||||
for (var i = 0; i < l; i++) q[i]();
|
nextTickIndex = 0;
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
if (i + 1 < l) {
|
|
||||||
nextTickQueue = q.slice(i + 1).concat(nextTickQueue);
|
|
||||||
}
|
|
||||||
if (nextTickQueue.length) {
|
|
||||||
process._needTickCallback();
|
|
||||||
}
|
|
||||||
throw e; // process.nextTick error, or 'error' event on first tick
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
process.nextTick = function(callback) {
|
process.nextTick = function(callback) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
before
|
before
|
||||||
|
|
||||||
node.js:*
|
module.js:311
|
||||||
throw e; // process.nextTick error, or 'error' event on first tick
|
throw err;
|
||||||
^
|
^
|
||||||
RangeError: Maximum call stack size exceeded
|
RangeError: Maximum call stack size exceeded
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
before
|
before
|
||||||
|
|
||||||
node.js:*
|
module.js:311
|
||||||
throw e; // process.nextTick error, or 'error' event on first tick
|
throw err;
|
||||||
^
|
^
|
||||||
MyCustomError: This is a custom message
|
MyCustomError: This is a custom message
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
before
|
before
|
||||||
|
|
||||||
node.js:*
|
module.js:311
|
||||||
throw e; // process.nextTick error, or 'error' event on first tick
|
throw err;
|
||||||
^
|
^
|
||||||
[object Object]
|
[object Object]
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
before
|
before
|
||||||
|
|
||||||
node.js:*
|
module.js:311
|
||||||
throw e; // process.nextTick error, or 'error' event on first tick
|
throw err;
|
||||||
^
|
^
|
||||||
ReferenceError: foo is not defined
|
ReferenceError: foo is not defined
|
||||||
at evalmachine.<anonymous>:*
|
at evalmachine.<anonymous>:*
|
||||||
at Object.<anonymous> (*test*message*undefined_reference_in_new_context.js:*)
|
at Object.<anonymous> (*test*message*undefined_reference_in_new_context.js:*)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user