查找 .then 链中哪个 Promise 失败了

问题描述 投票:0回答:1

我正在尝试在我的节点 + Express 应用程序中设计一个在末尾带有捕获错误的承诺链。在下面的示例中,如果任何一个“then”函数出错,我将不得不向后查找错误消息中的哪一个。有没有更简单的方法来编写 catch 函数?

    new Promise(function(resolve, reject) {
       resolve(groupId);
    })
    .then(sid => getGuestGroup2(sid))matching carts
    .then(group =>getProducts(group))//add products
    .then(result2 =>getPrices(result2))
     .catch(error => { // (**)
        console.log('Error on GET cart.js: '+error);
        res.sendStatus(500);
      });
javascript node.js express promise es6-promise
1个回答
1
投票

Promise
链接足够通用,不包含开箱即用的“哪一步失败”类型的信息。您可能会尝试从堆栈跟踪中对其进行解码,但在我看来,这比其价值要多得多。您可以使用以下几个选项来确定哪个步骤失败了。

选项1

在错误对象上设置一个额外的属性(作为指示器),可以在 catch 块中对其进行解码,以确定错误源自链中的哪一步。

function predictibleErrors(promise, errorCode) {
    return Promise.resolve(promise)
        .catch(err => {
            const newErr = new Error(err.message);
            newErr.origErr = err;
            newErr.errorCode = errorCode;
            throw newErr;
        });
}

Promise.resolve(groupId)
    .then(sid => predictibleErrors(getGuestGroup2(sid), 'STEP_1')) // matching carts
    .then(group => predictibleErrors(getProducts(group), 'STEP_2')) // add products
    .then(result2 => predictibleErrors(getPrices(result2), 'STEP_3'))
     .catch(error => { // (**)
        console.log('Error on GET cart.js: '+error);

        // Check error.errorCode here to know which step failed.

        res.sendStatus(500);
      });

选项2

好老办法,在每一步后捕获,然后重新抛出以跳过后续步骤。

function chainedErrorHandler(errCb) {
    return (err) => {
        if(err.handled) {
            throw err;
        }
        errCb(err);
        err.handled = true;
        throw err;
    };
}

Promise.resolve(groupId)
    .then(sid => getGuestGroup2(sid)) // matching carts
    .catch(chainedErrorHandler(err => {
        console.log('step 1 failed');
    }))
    .then(group => getProducts(group)) // add products
    .catch(chainedErrorHandler(err => {
        console.log('step 2 failed');
    }))
    .then(result2 => getPrices(result2))
    .catch(chainedErrorHandler(err => {
        console.log('step 3 failed');
    }))
    .catch(error => {
        // Some step has failed before. We don't know which one, here,
        // but requisite processing for each failure could have been done
        // in one of the previous catch blocks.
 
        console.log('Error on GET cart.js: '+error);
        res.sendStatus(500);
    });

请注意,我们在选项二中所做的事情也可以直接通过底层方法来完成。例如。

getGuestGroup2
getProducts
可以在其抛出的错误对象上包含
errorCode
或类似属性。在此示例中,我们知道步骤 1 或步骤 2 失败,但不知道原因。如果底层方法设置相同,它们可以包含更准确的错误代码,并了解操作失败的原因。我没有采取这条路线,因为这些方法不包含在您的示例中,并且据我所知它们可能不在您的控制范围内。

© www.soinside.com 2019 - 2024. All rights reserved.