Side navigation
#12884 closed bug (duplicate)
Opened November 12, 2012 10:51AM UTC
Closed November 12, 2012 02:48PM UTC
Errors thrown on callback handlers can break the original promise
Reported by: | Alex Kalderimis <alex@intermine.org> | Owned by: | |
---|---|---|---|
Priority: | undecided | Milestone: | None |
Component: | unfiled | Version: | 1.8.2 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
If errors are thrown by callback handlers passed to ''jQuery.Deferred.then'' then they will trigger a number of unspecified and dangerous behaviours:
- Callbacks don't catch errors thrown inside them. This is the most minor issue, but it would make a lot of sense to catch errors and issue a rejection, and this simple change would deal with the consequences below.
- As it is uncaught, the error will blow the stack in the current context of execution, rather than asynchronously, blowing up co-ordinating code, even when the function itself was never called explicitly. This is surprising, but not completely unreasonable; it should be specified in documentation.
- The call to ''jQuery.Deferred.then'' will not return a usable value. It should be part of the contract that then will always return a null safe value implementing the promise interface, even if it is just a rejected promise that reports its own failure to be created. This also points to an inconsistency in interface, in that a error thrown in a callback applied to an unresolved promise will return a new promise, but it the original promise was already resolved, then we will get this different and undesired behaviour.
- Most seriously the original promise is now broken, and will no longer respond to callbacks passed to then at all. This completely breaks the contract, whereby a promise's callbacks do not affect each other and a promise once resolved or rejected will always respond to new callbacks.
A demonstration of this set of issues is available at: http://jsfiddle.net/3geX6/2/
This whole issue could be resolved by having ''then'' (which is meant to return a sensible value, so this applies to ''then'' more so than to ''done'', ''fail'' or ''always'') catch its errors and return a rejected promise containing the error.
Sorry; pasted the wrong version of the jsfiddle example - this one is better:
http://bugs.jquery.com/ticket/12884