Consider this block of code:
getUser(userId)
.catch(function(error){
crashreporter.reportError(\'User DB failed\', error);
// show us
Here is how you can accomplish "cancelling" the chain without ever nesting callbacks. This is why promises are a solution to "callback hell"...
var errors = {
USER: 'User DB failed',
CHARGE: 'ChargeId DB failed',
HISTORY: 'chargeHistoryId DB failed',
};
function onError(type, error) {
throw {
message: type,
error: error
}
}
getUser(userId)
.then(chargeCreditCard, onError.bind(null, errors.USER))
.then(saveChargeId, function (error) {
if (error.message === errors.USER) throw error
else onError(errors.CHARGE, error);
})
.then(associateChargeToUsers, function(error) {
if (error.message === errors.CHARGE || error.message === errors.USER) throw error
else onError(errors.HISTORY, error);
})
.then(finalFormatting, function(error) {
crashreporter.reportError(error.message, error.error);
})
.then(showToUser);
Essentially, if the first promise fails, you pass its error down the chain of failure callbacks and when it reaches the end, where it gets logged. No other promises are created, so you have effectively "cancelled" the operation on first failure.