使用A + Promises处理预期与操作错误

时间:2015-10-06 19:55:00

标签: javascript bluebird es6-promise

我现在已经使用蓝鸟的承诺了一段时间,而我真正喜欢的一件事就是他们实施了一个目标' catch'以及用于显式捕获OperationalErrors的.error短手。

这允许我做以下事情:

var p = new Promise(/*stuff*/);
p.then(function(){ /* good */ })
.error(function(){ /* only handle expected operational cases */ });
.catch(function(){ /* if needed, handle unexpected errors, usually just crash */});

然而在承诺规范中,没有" .error",最接近的东西看起来更像:

var p = new Promise(/*stuff*/);
p.then(function(){ /* good */ })
.catch(function(e){
        if (e instanceof ThingIExpect){
            //do something
        }else{
            throw e; //die
        }
});

但.error语法的一个好处是,如果不使用catch,这样的代码就会崩溃,这就是应该做的事情:

"use strict";
var p = new Promise(function(f,r){
    a = 10; //Reference Error
    f(true);
});


p.then(function(val){
    console.log(val); //never gets hit - ReferenceError
}).error(function(e){
    console.log(e); //never gets hit - ReferenceError
});

这里我的引用错误只是崩溃了。使用蓝鸟我永远不必担心一个初级开发人员这样做,只要我lint,或只在需要时使用.catch的代码审查。

"use strict";
var p = new Promise(function(f,r){
    a = 10; //Reference Error
    f(true);
});


p.then(function(val){
    console.log(val); //never gets hit - ReferenceError
}).catch(function(e){
   //attempt to handle ReferenceError instead of just crashing.
});

还没有OperationalError的概念,拒绝只是类型错误。因此,除非您总是拒绝自己的自定义类型,否则很难明确检查拒绝与其他可能的错误。

所有这些都说了,最后问题是:

在使用本机Promises编写应用程序或将A +规范实现到字母的内容时,处理操作与预期错误的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

考虑将“预期失败”转移到成功案例中,而不是拒绝自定义错误。换句话说,而不是:

var p = new promise(function (f, r) {
    var result = getResult();
    if (result > 5) { f(result); }
    else { r(new Error("result was too small")) }
});

尝试:

var p = new promise(function (f, r) {
    var result = getResult();
    if (result > 5) { 
        f({success: true, result: result}); 
    }
    else { 
        f({success: false, reason: "result was too small"}); 
    }
});

现在您知道只会为意外失败调用错误案例处理程序,这是您感兴趣的内容。

另一个好处是,您现在正在明确地对操作错误进行建模,并且鼓励编写履行处理程序的人考虑处理success: false案例。