简体   繁体   English

为什么在 promise 链的末尾捕获没有捕获所有错误?

[英]Why catch at the end of promise chain is not catching all the errors?

i have simple validation promises in my code which i execute like so我的代码中有简单的验证承诺,我像这样执行

inBlacklist(address)
    .then(isUsed(payments))
    .then(isProcessed(ref_num))
    .then(validateType(type))
    .catch((err) => {
        console.log(err);
        return res.status(400).send({ message: err.message });
    });

Which basically checks if the payment is propertly processed or not.这基本上检查付款是否得到正确处理。

Here are the promises这里是承诺


export const isUsed = (payments) =>
    new Promise((resolve, reject) => {
        if (payments) {
            const paymentsData = payments.map((i) => {
                i.date = moment(i.date).startOf('minute').format('YYYY-MM-DD HH:mm');
                i.amount = parseInt(i.amount);
                return i;
            });

            Transaction.findOne(paymentsData)
                .exec()
                .then((data) => {
                    if (data.length) {
                        reject({ message: 'Payment is already used', status: 409 });
                    } else {
                        resolve(false);
                    }
                })
                .catch((err) => {
                    reject(err);
                });
        }
    });

export const inBlacklist = (address) =>
    new Promise((resolve, reject) => {
        Blacklist.exists({ blocked: true, address })
            .then((blocked) => {
                
                if (blocked) {
                    return reject({ message: 'Address is in blacklist', status: 406 });
                } else {
                    return resolve(false);
                }
            })
            .catch((err) => {
                return reject(err);
            });
    });

export const isProcessed = (ref_num) =>
    new Promise((resolve, reject) => {
        if (ref_num) {
            Transaction.exists({ ref_num, status: { $in: ['processing', 'expired', 'resolved'] } })
                .exec()
                .then((data) => {
                    return reject({ message: 'Payment is already used', status: 422 });
                })
                .catch((err) => {
                    reject(err);
                });
        } else {
            return resolve(false);
        }
    });

export const validateType = (type) =>
    new Promise((resolve, reject) => {
        const validTypes = ['bitcoin', 'dash'];

        if (validTypes.includes(type)) {
            return resolve();
        } else {
            return reject({ message: 'Invalid crypto type', status: 422 });
        }
    });

Now when i call the chain, it only works in case when inBlacklist was rejected.现在,当我调用链时,它仅在inBlacklist被拒绝时才有效。 For the others it appears as an unhandled error, which just shows up on console and doesnt return the response for api.对于其他人,它显示为未处理的错误,仅显示在控制台上并且不返回 api 的响应。

I have also tried this我也试过这个

Promise.all([inBlacklist(address), isUsed(payments), isProcessed(ref_num), validateType(type)]).catch((err) => {
    return res.status(err.status || 400).send({ message: err.message });
});

Which works fine, but what if i want to use the first variant?哪个工作正常,但是如果我想使用第一个变体怎么办? Why i cant catch all the promise rejections in one.catch block?为什么我无法在 one.catch 块中捕获所有 promise 拒绝?

Looks like the issue is that isUsed is being executed immediately rather than after inBlacklist resolves, so your .then() is being given a Promise object rather than a callback function.看起来问题是isUsed正在立即执行,而不是在inBlacklist解决后执行,因此您的 .then .then()被赋予 Promise object 而不是回调 ZC1C425268E68385D1AB5074C17A94。 It's just like if you wrote a(b(c));就像你写a(b(c)); , b is executed first and then the return value is passed to a . , b首先执行,然后将返回值传递给a

Instead, you want to pass to .then a callback function that executes the next function, so try using arrow functions inside the then s, like so:相反,您想传递给.then一个回调 function 以执行下一个 function,因此请尝试在then s 中使用箭头函数,如下所示:

inBlacklist(address)
    .then(() => isUsed(payments))
    .then(() => isProcessed(ref_num))
    .then(() => validateType(type))
    .catch((err) => {
        console.log(err);
        return res.status(400).send({ message: err.message });
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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