Why is the Promise reject() in my jest.mock going to a then() rather than a catch()?

你离开我真会死。 提交于 2019-12-01 18:33:04

Why is the Promise reject() in my jest.mock going to a then() rather than a catch()?

Your .catch() handler is converting a rejected promise into a resolved promise and thus only the outer .then() handler is called.

When you use .catch() like this:

.catch((err) => {
    return err;
});

and do not rethrow the error or return a rejected promise, then the rejection is considered "handled" and the returned promise becomes resolved, not rejected. This is just like using a try/catch. In a catch handler, the exception is handled unless you throw it again.

You can see that in this simple snippet:

new Promise((resolve, reject) => {
    reject(new Error("reject 1"));
}).catch(err => {
    // returning a normal value here (anything other than a rejected promise)
    // causes the promise chain to flip to resolved
    return err;
}).then(val => {
    console.log("Promise is now resolved, not rejected");
}).catch(err => {
    console.log("Don't get here");
});

There's really no reason for either of these:

.then((result) => {
    return result;
})
.catch((err) => {
    return err;
});

You can just remove both of them. The .then() handler is just superfluous code and the .catch() handler eats the rejection and turns it into a resolved promise.

If you want to keep the .catch() handler, but allow the rejection to propagate upwards, then you need to rethrow.

.catch((err) => {
    console.log(err);
    throw err;       // keep promise rejected so reject will propagate upwards
});

Because you've converted the rejection into a resolution:

.catch((err) => {
    return err;
});

If you want the rejection to propagate out of getItemInfo, remove the catch handler from getItemInfo.

Remember that catch and then both create and return promises, and their handlers are treated the same:

  1. If you return a value from them, the promise then/catch created is resolved with that value.

  2. If you return a thenable from them, the promise then/catch created is slaved to that thenable (resolved or rejected based on what that thenable does).

  3. If you throw within them, the promise then/catch created is rejected with that error.

You only need a catch handler if:

  • You're not passing the chain along to something else (which you are in getItemInfo), or

  • You need to transform an error in some way, either by transforming it into a resolution (recovery) or transforming it into a different error. To do the latter you throw or return a promise that is or will be rejected.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!