Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Add optional global error trap #94

Closed
wants to merge 1 commit into from

3 participants

@ef4

Sometimes window.onerror is just not good enough. For example, under
Chrome you lose your stack trace.

This exposes a new function on Q that lets you set a global error
handler, which is called whenever Q.end() would have otherwise generated an
unhandled exception. Example usage:

Q.onError(function(err){
  // Post your error to the server...
});

Note that if you still want the unhandled exception too (which is helpful in the console), you can just make your onError handle rethrow.

@ef4 ef4 Add optional global error trap
Sometimes window.onerror is just not good enough. For example, under
Chrome you lose your stack trace.

This exposes a new function on Q that lets you set a global error
handler, for whenever Q.end() would have otherwise generated an
unhandled exception.
48935bc
@domenic
Collaborator

I like this, and it certainly would make testing easier. Let's get some buy-in from @kriskowal before merging, but I'm sure it'll get in in some form.

The only question I have is whether there should be a single global error handler, which multiple users of Q can overwrite, or whether it should be an event-dispatching system where multiple calls to Q.onError result in multiple listeners being registered. I can see arguments either way.

@ef4

Yeah, I considered supporting multiple listeners but couldn't come up with a practical reason I'd ever need that.

@kriskowal
Owner

I will entertain a Q.onerror = handler API for this, but not this patch as-is.

@kriskowal kriskowal closed this
@ef4

But doesn't defend(exports) rule out that kind of API?

As far as I can see (in Chrome), I'm unable to set properties on Q from outside the Q module itself.

@kriskowal kriskowal reopened this
@kriskowal
Owner

@e4f, ah right. Will have to think more on it.

@ef4 ef4 referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@ef4 ef4 referenced this pull request from a commit in ef4/q
@ef4 ef4 Don't mangle stack traces when an exception is seen twice
It's possible for the same exception to hit two different "end()"
points, causing it to pass through the stack trace formatter twice.

On the second pass, error.stack is already a string, and the formatter
mangles it by inserting newlines after every character.

The unit test included in this pull request depends on my earlier pull
request #94. That global error trap is pretty helpful for tests like
this.
fbd0b25
@domenic
Collaborator

@kriskowal, I'd really like something like this. One more consideration: #111 calls for something like Q.stackJumpLimit = 5.

In light of these two, I see two options:

  1. Un-defend exports, perhaps selectively making all existing properties non-writable and non-configurable. This allows us to align with existing APIs a bit better, viz. window.onerror and Error.stackTraceLimit as settable properties.
  2. Introduce a Q.configureErrors({ uncaughtTrap, stackJumpLimit }) call.
@kriskowal
Owner

@domenic Let’s remove the defense of exports and add onerror and longStackTraceLimit.

@domenic domenic closed this pull request from a commit
@domenic domenic Introduce `Q.onerror` for a global rejection trap.
- Fixes #94.
- Tests switched to use this instead of the previous glob of code for doing similar things.
- Exports are now undefended (i.e. not frozen).
cdd8198
@domenic domenic closed this in cdd8198
@dfilatov dfilatov referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 29, 2012
  1. @ef4

    Add optional global error trap

    ef4 authored
    Sometimes window.onerror is just not good enough. For example, under
    Chrome you lose your stack trace.
    
    This exposes a new function on Q that lets you set a global error
    handler, for whenever Q.end() would have otherwise generated an
    unhandled exception.
This page is out of date. Refresh to see the latest.
Showing with 10 additions and 0 deletions.
  1. +10 −0 q.js
View
10 q.js
@@ -1299,6 +1299,12 @@ function fin(promise, callback) {
});
}
+var globalErrorTrap = null;
+exports.onError = onError;
+function onError(handler){
+ globalErrorTrap = handler;
+}
+
/**
* Terminates a chain of promises, forcing rejections to be
* thrown as exceptions.
@@ -1326,7 +1332,11 @@ function end(promise) {
error.stack = formatStackTrace(error, combinedStackFrames);
}
+ if (globalErrorTrap){
+ globalErrorTrap(error)
+ } else {
throw error;
+ }
});
});
}
Something went wrong with that request. Please try again.