简体   繁体   中英

Handling errors in promise chains

There are two categories of errors that might occur in a promise chain.

  1. Errors thrown from inside the promise chain (dealt with by .catch )
  2. Errors thrown when configuring the promise chain

My question is how best to deal with the latter.

For example, in the following .catch will not catch exceptions thrown by foo before it has had a chance to return a promise.

function go() {
    return foo()
        .then(bar)
        .catch(bam);
}

Clearly I can wrap the contents of go in a try-catch block.

But would it be better to return an immediately rejected promise from a catch block in foo to "maintain the API" and have a promise-based interface for all eventualities?

Alternatively, you can include foo in the chain, like this

Promise.resolve()
    .then(foo)
    .then(bar)
    .catch(bam);

Now, even if the foo throws, the bam will take care of it.


Or, build a wrapper over foo ,

function promiseWrapper(func) {
    try {
        return Promise.resolve(func());
    } catch (e) {
        return Promise.reject(e);
    }
}

And then use it, instead of foo , like this

function go() {
    return promiseWrapper(foo)
        .then(bar)
        .catch(bam);
}

Or you can be more explicit and do:

function foo() {
    try {
        // some staff which should return promise
    }
    catch(e) {
        retrun Propmise.reject('the reason');
    }
}

then use

function go() {
    return foo()
        .then(bar)
        .catch(bam);
}

Now, you don't need to change all usages of your foo .

Use the proposed (Stage 3) async functions. They are guaranteed to return a promise, so you don't have to worry about capturing synchronous exceptions while setting up the promise chain.

(async () => {throw new Error})().catch(::console.error)

You can promisify foo so that any error happens within foo triggers reject function automatically. Such as;

 function foo(){ throw new Error("booom"); return Promise.resolve(42); } function bar(v) { console.log("I am resolved with " + v())} function baz(v) { console.log("I am rejeceted because of a " + v)} function go() { Promise.resolve(foo) .then(bar) .catch(baz); } go(); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM