Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
Fix process.nextTick throw call sites
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
felixge authored and isaacs committed May 9, 2012
1 parent ee437c0 commit 8140333
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 32 deletions.
12 changes: 8 additions & 4 deletions src/node.cc
Expand Up @@ -255,9 +255,7 @@ static void Spin(uv_idle_t* handle, int status) {
Tick();
}


static Handle<Value> NeedTickCallback(const Arguments& args) {
HandleScope scope;
static void StartTickSpinner() {
need_tick_cb = true;
// 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" -
Expand All @@ -268,9 +266,12 @@ static Handle<Value> NeedTickCallback(const Arguments& args) {
uv_idle_start(&tick_spinner, Spin);
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) {
assert(handle == &prepare_tick_watcher);
Expand Down Expand Up @@ -1694,6 +1695,9 @@ void FatalException(TryCatch &try_catch) {
emit->Call(process, 2, event_argv);
// Decrement so we know if the next exception is a recursion or not
uncaught_exception_counter--;

// This makes sure uncaught exceptions don't interfere with process.nextTick
StartTickSpinner();
}


Expand Down
24 changes: 8 additions & 16 deletions src/node.js
Expand Up @@ -180,26 +180,18 @@

startup.processNextTick = function() {
var nextTickQueue = [];
var nextTickIndex = 0;

process._tickCallback = function() {
var l = nextTickQueue.length;
if (l === 0) return;
var nextTickLength = nextTickQueue.length;
if (nextTickLength === 0) return;

var q = nextTickQueue;
nextTickQueue = [];

try {
for (var i = 0; i < l; i++) q[i]();
}
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
while (nextTickIndex < nextTickLength) {
nextTickQueue[nextTickIndex++]();
}

nextTickQueue.splice(0, nextTickIndex);
nextTickIndex = 0;
};

process.nextTick = function(callback) {
Expand Down
6 changes: 3 additions & 3 deletions test/message/stack_overflow.out
@@ -1,6 +1,6 @@
before

node.js:*
throw e; // process.nextTick error, or 'error' event on first tick
^
module.js:311
throw err;
^
RangeError: Maximum call stack size exceeded
6 changes: 3 additions & 3 deletions test/message/throw_custom_error.out
@@ -1,6 +1,6 @@
before

node.js:*
throw e; // process.nextTick error, or 'error' event on first tick
^
module.js:311
throw err;
^
MyCustomError: This is a custom message
6 changes: 3 additions & 3 deletions test/message/throw_non_error.out
@@ -1,6 +1,6 @@
before

node.js:*
throw e; // process.nextTick error, or 'error' event on first tick
^
module.js:311
throw err;
^
[object Object]
6 changes: 3 additions & 3 deletions test/message/undefined_reference_in_new_context.out
@@ -1,8 +1,8 @@
before

node.js:*
throw e; // process.nextTick error, or 'error' event on first tick
^
module.js:311
throw err;
^
ReferenceError: foo is not defined
at evalmachine.<anonymous>:*
at Object.<anonymous> (*test*message*undefined_reference_in_new_context.js:*)
Expand Down

6 comments on commit 8140333

@mikeal
Copy link

@mikeal mikeal commented on 8140333 May 9, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

w00t!

@chilts
Copy link

@chilts chilts commented on 8140333 May 9, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no idea about the patch, but what it does is fantastic! :) Good on yer!

@nisc
Copy link

@nisc nisc commented on 8140333 May 9, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Felix has just fixed Node.js, I hope

@fivetanley
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

THANK YOU! This is fantastic!

@seriousManual
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thumbsup

@xer0x
Copy link

@xer0x xer0x commented on 8140333 May 17, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great idea

Please sign in to comment.