Wednesday, November 19, 2014

My comment on Remy Sharp's excellent blog post

My comment on Remy Sharp's excellent blog post

The "Always end with a catch" pattern in probably not good advice. One should only add a catch if and only if one had wrapped the same program in a try-catch-block in a synchronous program.

If a catch is necessary to show the error on the console then that is a bug in the promise implementation; working around that in user code is bad because another party may add a catch block that may actually be handling the error but now it still goes to the console and your example just prints the stack but fails to print the error message – the library just can do a much better job at this.

Some promise libraries ship with this "bug" because in a purist view of promises (probably involving the word monad) it is not a nice that this requires adding catch handlers in the same execution stack as the promise was created – but real world programming has shown that there is absolutely nothing worse for programmer's productivity but an error that was thrown but then just "eaten" by the system instead of notifying the programmer. Basically you sit in front of a machine and it doesn't work, but it doesn't tell you why.

This is why Chrome changed the behavior: Uncaught promise errors will go to the console (works in Canary, apparently not yet in stable). I don't have a good list of promise libraries that do the right thing, but the one I work on does :)
Another thing that goog.Promise does to help debugging is that it "throws" every explicit call to reject ( The error is immediately caught and ignored – but if you set your DevTools to "break on caught exceptions" it will also break for rejects – which is what you want since they are semantically equivalent to throws.