Error handling in Q promise

2019-07-20 06:30发布

问题:

I'm a bit confused understanding Q promise error handling. Let's say I have the following functions (for demonstration only):

function first() {
    console.log('first');
    var done = Q.defer();
    done.resolve('first');
    return done.promise;
}

function second() {
    console.log('second');
    var done = Q.defer();
    done.resolve('second');
    return done.promise;
}

function third() {
    console.log('third');
    var done = Q.defer();
    done.resolve('third');
    return done.promise;
}

function fourth() {
    console.log('fourth');
    var done = Q.defer();
    done.resolve('fourth');
    return done.promise;
}

function doWork() {
    return first().then(function() {
        return second();
    }).then(function() {
        return third()
    }).then(function() {
        return fourth();
    });
}

doWork().catch(function(err) {
    console.log(err);
});

Everything went fine.

Now that if in second, third or fourth function, I've got some errors (thrown by an async call for example), I could catch it gracefully.

For example, if in second, third or fourth function, I add:

throw new Error('async error');

The error is caught. Perfect!

But what makes me confused is that if the error is thrown in first function, the error is not caught and that breaks my execution.

Please someone tell me why or what I am doing wrong?

Thanks a lot!

回答1:

Only exceptions in then callbacks are caught by promise implementations. If you throw in first, the exception will bubble and would only be caught by a try-catch statement.

That's exactly why asynchronous (promise-returning) functions should never throw. Instead, reject the promise you're returning (done.reject(…) or return Q.reject(…)). If you don't trust your function, you can use Promise.resolve().then(first).… to start your chain.



回答2:

Wrap the logic that can break in a try block and reject the promise with the error in the catch block.

var def = q.defer();
try {
  // sync or async logic that can break
}
catch (ex) {
  q.reject(ex);
}
return def;