promises-aplus / unhandled-rejections-spec

Discussion and drafts of possible ways to deal with unhandled rejections, across implementations
6 stars 0 forks source link

Fail-fast always #7

Open ForbesLindesay opened 11 years ago

ForbesLindesay commented 11 years ago

Fail fast all the time, but have a method to explicitly state that you intend to handle a rejection in a future turn of the event loop.

You could perhaps only throw if a rejection is not handled for say 1 second.

ForbesLindesay commented 11 years ago

I personally am not really in favour of this, but I think it would be preferable to #4 as we wouldn't see as many implementations break in the 'strict' mode

ForbesLindesay commented 11 years ago

Actually I'm coming round to this idea. I don't think the 1 second idea is a good one, it introduces insanely non-deterministic behaviour.

We could add a .preserve() method that essentially means "I promise I will handle exceptions later or it doesn't matter if this throws an exception". It would return this rather than creating a new rejected promise.

The reason I think this is a plausible idea is that I think users rarely actually parse promises to the next turn of the event loop. Libraries do it all the time (e.g. all methods can be implemented as a reduce which then has this problem) but users rarely do it directly themselves.

domenic commented 11 years ago

I don't think that's feasible, sadly. preserve would have to be implemented by everyone before libraries could use it, and in general I'm not sure "preserving" is any better than "capping" (with done/end).

The difference being, I guess, that mostly libraries would preserve, while mostly users will cap. While this seems like an attractive tradeoff at first, it fails from an interoperability standpoint. Users are precisely the ones who choose their promise implementation, while libraries have to be agnostic.

ForbesLindesay commented 11 years ago

Yes, the only advantage I see is that beginner's use promise libraries, and experts write them (or at least that's how it should be), and at the moment beginner's are being stung by the poor error handling behaviour.

zpdDG4gta8XKpMCd commented 8 years ago

It should have been always fail fast from the day one. Now the spec is messed up and you guys trying to jump out of your pants to fix it. Throwing exceptions is a side effect, all side effects need to be handled explicitly which means if I mean to propagate a rejection I have a way to do it, it I want to crash I have a way to do it to. The spec ruled out the latter option leaving no choice made a side effect behaviour implicit. Ugh

bminer commented 8 years ago

I like the fail-fast approach the best. Fail-fast seems like the safest approach because you can write promises like this:

var promise = new Promise(function(resolve) {
    kjjdjf();  // function that doesn't exist because I failed at typing
});

I feel like a syntax error like this should definitely result in an uncaught exception and preferably crash the program (or in browsers, log to console and send to onerror). In async/Promise land, the behavior of an unhandled rejection should be the same as synchronous code. The whole point of Promises are to parallel synchronous code nicely.

I like the .preserve() idea that @ForbesLindesay proposed... but it's not much different than just doing .catch(function nop(){}) on the Promise. You can always register a nop() function on the Promise and ignore rejections... then sometime later when you actually want to handle the rejection, you can add another catch handler to the original Promise.

What if calling catch(cb) returned a new Promise while calling catch() with no callback argument behaved like the proposed .preserve() and just returned this Promise?