I have a function doSomething()
that returns a promise chain, utilizing the Q framework. The contents are similar to something like:
loadDataSet :
You can't throw exceptions inside then
as no one will able to catch it. Instead, create a new Q.defer
and call reject on it whenever there's an error
loadDataSet : function (params) {
var deferred = Q.defer()
Q.fcall(function() {
//Do Something
}).then(function(){
//Do Something Else
deferred.reject('error message')
}, deferred.reject)
return deferred.promise
}
then use it like this
loadDataSet().then(function (data) {
//ok, got data
}).catch(function (err) {
//error!
})
Well, this is going to a be a bummer.
While a lot of promise libraries let you do this and will report unhandled rejections for you - in Q you have no methods to automatically detect these failures.
You have to Use .done
or change a promise library. Heck, even native promises are going to be able to do this in a few days.
In Q your only realistic option is to use .done
, unlike then
done is not throw safe and you can throw exceptions from there and they won't be suppressed - this requires you to remember to always terminate chains with done
but it works:
myObj.loadDataSet(handleSuccess, handleError).done(); // will throw on rejection
Personally until Q fixes this and other issues I cannot recommend using it to anyone.
I've written a specification based on work by Domenic and Petka for promise libraries to be able to report errors globally and hook to them. Several libraries already implement this including bluebird and when. Domenic is working on a parallel specification for web browsers.
Currently supported or are going to be supported in the next few weeks are: bluebird, when, es6-promise, rsvp and native promises in io.
// log any unhandled promise rejections
process.on('unhandledRejection', function(reason, p){
console.log("Possibly Unhandled Rejection at: Promise ", p, " reason: ", reason);
// application specific logging here
});
As for browsers, something like:
window.addEventListener("unhandledrejection", function(e) {
var reason = e.detail.reason;
var promise = e.detail.promise;
console.log("Unhandled rejection", promise, reason);
});
This protocol is less supported but there are plans to include it in native promises. Currently Firefox native promises will report unhandled rejections and Chrome's will attempt too - but there are no browser hooks for it yet (it's coming though).
Note that teams are working on very interesting tooling. After a discussion with Paul Irish I'm convinced great things are going to come our way in terms of tooling for debugging promises in browsers that will make native promises almost as debuggable as bluebird promises (which is awesome!).