-
Notifications
You must be signed in to change notification settings - Fork 20.5k
Deferred: Warn on exceptions that are likely programming errors #2737
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Yea, I wonder if |
src/deferred.js
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still don't see this as library code. The whole mess is more appropriate for userland.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd agree if the developer ergonomics weren't so horrific. If the default is to swallow but we just add the ability for a hook, people won't know enough to add a hook. Like I said in the meeting, devs need a solution really bad, so here is a really bad solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about pluging in this "error-handler" via a separate AMD Module...? That way one can build jQuery without it (for production) and with it for development etc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@staabm not a bad idea
|
Is my understanding correct that this:
|
No, it only warns on the derivative
Yes, non-exception rejections (not an exception or explicitly |
What I mean is that this isn't a hook for unhandled exceptions. It's a hook for all exceptions. |
Oh, sorry, yes. Exceptions like |
src/deferred.js
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we do error.stack here?
|
Pushed a few changes here. I tried |
src/deferred/exceptionHook.js
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because the Deferred is resolved through a setTimeout it loses the stack. We could use some chicanery to save a stack beforehand but that would impact size and performance for the comparatively rare case where an exception occurs. So I pulled out the stack trace entirely since it only refers to things inside jQuery itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does simply accessing the stack property of an Error have a perf impact? You suggested this in the meeting, but you could also provide jquery.longStackTraces.js as a plugin or something to get functionality similar to Bluebird as long as the appropriate hooks exist in core
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding a hook so that a plugin could provide better stack traces seems like a good way to go, I'm looking into it.
* The stack is worthless because the promise is resolved by setTimeout() * New module created for exceptionHook() * The .stack property is not useful for our purposes
c311290 to
79d7c6b
Compare
|
Updated to add the stack hook. I'm not fully confident about what's here, would love a review, esp from @gibson042. |
test/unit/deferred.js
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be removed but I wanted to be sure we had the valid stack at this point of execution.
src/deferred/exceptionHook.js
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not that this matters in the slightest, but seeing as how you're accessing the global immediately above this as feature detection, is there any reason to .call rather than just window.console.warn(...)? Might even save some bytes ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, technically I could just let gzip do its thang and avoid the variable, which would also remove the need for the .call. I'm okay with that if people prefer it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds like a good idea.
|
I've put together a plugin that uses the hook for collecting the stack and then shows it when an exception occurs. In the README I mention that having to collect the stack in advance makes Deferreds slower by roughly 2x which is why it isn't on by default. However, since it's such a small amount of code I wonder whether we shouldn't just have a flag or other simple one-liner to enable this rather than making people load another module/plugin to do it. |
|
I like that it's a separate plugin, with its own README explaining why it's necessary. A flag can easily be kept on by accident. |
Fixes gh-2736
Still a WIP with some details to be worked out. I'm not really happy with the stack trace that results, it's only showing the immediate prior call. The gist, however, is that nearly all exceptions of these types are programming mistakes and should be reported ASAP. If devs don't like being warned about them they can set
jQuery.Deferred.exceptionHook = nulland not be bothered, or define a custom hook that filters out the noisy false positives.