简体   繁体   English

使用Promise链进行错误处理

[英]Error handling with promises chain

I have a chain of promises 我有许诺

promisedStep1()
    .then(promisedStep2)
    .then(promisedStep3)
    .then(promisedStep4)
    .then(function (value4) {
        // Do something with value4
    })
    .catch(function (error) {
        // Handle any error from all above steps
    });

And I need to know at which step I got an error. 我需要知道在哪一步出错。

If I add catch to each promised step 如果我在每个承诺的步骤中添加捕获

promisedStep1()
    .catch(function(){
        throw {code: 1}
    })
    .then(promisedStep2)
    .catch(function(){
        throw {code: 2}
    })
    .catch(function (error) {
        console.log('error in ', error.code);
    });

code would be always 2, because it goes from first catch to second. code始终为2,因为它从第一次捕获到第二次捕获。

What are the techniques in handling such errors? 处理此类错误有哪些技术?

Edit 编辑

Found a way: 找到了一种方法:

function promisedStep1Wrapper(){
    return promisedStep1()
        .catch(function(){
            throw {code: 1};
        });
}

function promisedStep2Wrapper(){
    return promisedStep2()
        .catch(function(){
            throw {code: 2};
        });
}

promisedStep1Wrapper()
    .then(promisedStep2Wrapper)
    .catch(function(err){
        console.log(err.code);
    });

Is this ok, or is there any better solution? 这样可以吗,还是有更好的解决方案?

Is this ok? 这个可以吗?

Yes, totally. 是的,完全是。

or is there any better solution? 还是有更好的解决方案?

"Better" I don't know, but there are others for sure. 我不知道“更好”,但是肯定还有其他人。 One approach would be to only handle those errors you expect - the ones from the previous step, and rethrow everything else. 一种方法是仅处理您期望的那些错误-上一步中的那些错误,然后重新抛出其他所有错误。 Some libraries like Bluebird do have dedicated helper function for this definitely superior approach. 诸如Bluebird之类的某些库确实具有专用于此绝对优越方法的帮助程序功能。 It would basically look like this: 基本上看起来像这样:

promisedStep1() // throws Step1Error
.catch(function(err) {
    if (!(err instanceof Step1Error)) throw err;
    throw {code: 1};
})
.then(promisedStep2) // throws Step2Error
.catch(function(err) {
    if (!(err instanceof Step2Error)) throw err;
    throw {code: 2};
})
.catch(function(error) {
    if (!("code" in error)) throw error; // duck typing
    console.log('error in ', error.code);
})
.catch(function(error) {
    console.error("completely unexpected:", error);
});

Another approach is nesting and using the second then callback for dedicated error handling - see When is .then(success, fail) considered an antipattern for promises? 另一种方法是嵌套, then使用第二个then使用回调进行专门的错误处理-请参阅何时将.then(success,fail)视为对promise的反模式? for the difference to .then().catch() . .then().catch()的区别。 Using this, your code would look like 使用这个,你的代码看起来像

promisedStep1()
.then(function(res) {
    return promisedStep2(res)
    .then(function(res) {
        // do something
        return res;
    }, function(err) { // error in promisedStep2
        throw {code: 2};
    });
}, function(err) { // error in promisedStep1
    throw {code: 1};
})
.catch(function(error) {
    if ("code" in error)
        console.log('error in ', error.code);
    else
        console.error("completely unexpected:", error); // from "do something"
});

This approach works well and allow fine-grained control over attaching which handlers where, cleanly separating success and error paths, but is a bit syntactically confusing. 这种方法效果很好,并且可以对附加哪些处理程序的位置进行细粒度的控制,将成功路径和错误路径清晰地分开,但是在语法上有些混乱。

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

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