Skip to content

Conversation

@dmethvin
Copy link
Member

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 = null and not be bothered, or define a custom hook that filters out the noisy false positives.

@timmywil
Copy link
Member

Yea, I wonder if error.stack is a more appropriate stack trace than console.trace().

src/deferred.js Outdated
Copy link
Member

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.

Copy link
Member Author

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.

Copy link
Contributor

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

Copy link
Member

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

@scottgonzalez
Copy link
Member

Is my understanding correct that this:

  • Warns on all exceptions, not just unhandled exceptions
  • Only listens for thrown exceptions and not explicitly rejected promises?

@dmethvin
Copy link
Member Author

Warns on all exceptions, not just unhandled exceptions

No, it only warns on the derivative Error types listed there.

Only listens for thrown exceptions and not explicitly rejected promises?

Yes, non-exception rejections (not an exception or explicitly thrown error) don't go through this path. jQuery Deferred hasn't ever warned on unhandled explicit rejections (such as an ajax 404) so I don't feel bad about excluding them.

@scottgonzalez
Copy link
Member

Warns on all exceptions, not just unhandled exceptions

No, it only warns on the derivative Error types listed there.

What I mean is that this isn't a hook for unhandled exceptions. It's a hook for all exceptions.

@dmethvin
Copy link
Member Author

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 SyntaxError and explicitly thrown errors will pass through here.

src/deferred.js Outdated
Copy link
Member

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?

@dmethvin
Copy link
Member Author

dmethvin commented Dec 1, 2015

Pushed a few changes here. I tried sinon.spy but was getting an error from its guts and didn't really need it anyway.

Copy link
Member Author

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.

Copy link
Contributor

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

Copy link
Member Author

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
@dmethvin dmethvin force-pushed the 2736-unhandled-exceptions branch from c311290 to 79d7c6b Compare December 20, 2015 20:39
@dmethvin
Copy link
Member Author

Updated to add the stack hook. I'm not fully confident about what's here, would love a review, esp from @gibson042.

Copy link
Member Author

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.

Copy link
Contributor

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

Copy link
Member Author

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.

Copy link
Member

@mgol mgol Dec 23, 2015

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.

@dmethvin
Copy link
Member Author

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.

@timmywil
Copy link
Member

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.

@dmethvin dmethvin closed this in 36a7cf9 Jan 13, 2016
@dmethvin dmethvin deleted the 2736-unhandled-exceptions branch May 24, 2016 19:08
@lock lock bot locked as resolved and limited conversation to collaborators Jan 18, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Development

Successfully merging this pull request may close these issues.

10 participants