5 ms·
This gets so much easier with promises it's amazing: 1. You can `throw` in async functions (when things are promisified) and `.catch` async errors. 2. You can
by inglor 11y ago
This gets so much easier with promises it's amazing:
1. You can `throw` in async functions (when things are promisified) and `.catch` async errors.
2. You can't forget the error handling or ignore the `err` parameter, it will propagate until you handle it.
3. Did I mention propagation like with sync errors yet?
4. It's easy to build exception hierarchies. Libraries like bluebird provide typed and predicate catch blocks that let you do exception handling the way you want like in other languages.
5. Did I mention async/await or coroutines yet? You can use normal try/catch with promises as a language feature.
6. No Zalgo, if something might be async it should always be async to preserve execution order. `then` always runs asynchronously which means no timing issues and race conditions in errors and success values.
- bsimpson 11y agoThe biggest mistake in JS Harmony is silently swallowing async errors by default unless you add a .catch to a Promise chain.
- prawnsalad 11y agoThis has been my biggest pain point with Promises, I have spent hours trying to debug an issue only to find out I hadn't used an error handler in a Promise somewhere and an error was being thrown. It is so frustrating. I know some Promise libraries have an option to report unhandled errors which makes life a lot easier but there really should be something natively too.
- inglor 11y agoprocess.on('unhandledRejection', function(promise,reason) {` since io.js 1.3
- bsimpson 11y agoI haven't looked at io.js in a short while. Does it log to console.error by default (like Chrome now does)? This mistake is going to be most frustrating for those who don't realize that "unhandledRejection" is a case they even need to consider. People learning JS and having nothing happen when they run (erroneous) code are going to be pulling their hair out.
- inglor 11y agoThis is currently being discussed in io.js (and remember it's being backported to the main NodeJS branch). Feel free to come participate in the discussion.
- esamatti 11y agoChrome at least logs the error to console http://jsfiddle.net/sb1zqjdm/ http://jsfiddle.net/sb1zqjdm/ (using native promises) And it seems that the "Pause on exceptions" debugger feature works on unhandled promise errors. Doesn't seem too bad to me.
- bsimpson 11y agoThis is a recent addition due to complaints like mine. Hopefully it becomes standard, because it's the way it should have always been.
- esamatti 11y agoWonder whether there is anything to add to the standard. Isn't this just a devtools issue?
- BonsaiDen 11y agoThe standard should simply be changed to throw by default, but I guess the train has already left the station and so we're left with "bugs by design" before the spec has even been fully implemented by all vendors :( But then again, in it's current "minimal" state of design, the Harmony Promises are inferior to any of the dedicated Promise A Plus implementations out there (e.g. Bluebird) and at least under Node there is little to no reason to use the built-in Promise object at this point in time.
- inglor 11y agohttps://github.com/domenic/unhandled-rejections-browser-spec https://github.com/domenic/unhandled-rejections-browser-spec
- inglor 11y agoWell - the moral is to complain more, when I wrote and advocated for detection in io.js I needed people on my side - Domenic needs people to complain and help now for the browser spec - we're always a hand short :)
- inglor 11y agoNot if I can help it :) In io.js this is no longer an issue, you have a process event you can catch on "silent errors" to make them loud. This lands in NodeJS soon. Bluebird promises don't behave this way and have never done so.
- grandalf 11y agogreat! BTW would you use bluebird or es6 promises if starting a new project today?
- phpnode 11y agoinglor is a contributor to Bluebird, so I'd guess he'd say Bluebird. Bluebird is the much faster option and has a lot more features, if you're using babel (and a recent node/io.js) you can transpile async/await to bluebird coroutines for maximum performance and syntactic beauty.
- grandalf 11y agoIs there any chance Bluebird will become the standard in the future? Not sure if it makes sense to use a nonstandard approach, but would love to be convinced otherwise.
- phs2501 11y agoIMHO, very doubtful; Bluebird has a lot of (very useful) features that would be pretty burdensome to put into a specification. On the other hand, there's really no reason not to use Bluebird. It's easy to ensure that a promise you receive is a Bluebird promise: import Bluebird from 'bluebird'; const bluebirdPromise = Bluebird.resolve(promise); If `promise` is a Bluebird promise that will be a no-op, and if it's a foreign promise or thennable you'll get a new Bluebird promise that will resolve/reject when the foreign one does. (This is standard behavior; see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...) Since Bluebird promises are thennables, the reverse will be true if they're consumed by a different promise library. Given Bluebird's speed, superior debuggability, and features, there's really no reason not to use it a this point.
- qudat 11y agoAgreed! I literally just dealt with this eariler in the work week, spent hours trying to figure out why an error wasn't properly being thrown in my unit tests ... forgot to catch the promise chain -.- This applies to functions that are async as well in babel: async function get(url) { throw new Error('hi there'); } // wont throw the error get('http://google.com'); // catch the error get('http://google.com').catch(function(err) { throw err; });
- linkmotif 11y agoFWIW, I think JS swallows all async errors regardless of whether you use .catch(). If the error is thrown async, you can't catch it. Right?
- cwp 11y agoNo. This is the whole point of promises.
- dmethvin 11y agoPerhaps the gp meant this case? something().then(function(){ setTimeout(function(){ whoops_not_a_function(); }, 1000); }).catch(function(){ // nope, nothing to catch });
- phs2501 11y agoNo built-in help with native promises, but with something like Bluebird you'd prefer: something().then(() => { return Promise.delay(1000).then(() => { whoops_not_a_function(); }); }).catch(() => { // whoops_not_a_function is not defined }); ...or write Promise_delay yourself on top of native promises (but really just use Bluebird).
- linkmotif 11y agoYup this is what I meant. Thanks. Yeah arrow functions help.