如何使用基于承诺的node.js编码来区分编程错误和操作错误?

时间:2017-07-24 14:30:29

标签: javascript node.js promise

我对node.js很新,但我非常喜欢它。但是,我很想知道正确的错误处理。

在网络上有很多很好的资源,但它们大多都是旧的,并且指的是基于回调的编程。我更喜欢使用承诺。使用promise可以更容易地处理错误,因为您不必为可能发生的每个操作错误重复代码 - 相反,您只需捕获一次并处理(或传播给调用者)。

但是在节点中,如果发生程序错误,则必须区分错误类型并执行gracefull崩溃和重新启动应用程序。考虑这个基于回调的代码示例:|

function myFunc (input, cb){
    if(typeof input === 'undefined'){
        throw new Error('Invalid argument');
    }
    asinc1(input, function(e, data){
        if(err) return cb(e, null);
        asinc2(data, function(e, result){
            if(err) return cb(e, null);
            return cb(null, result);
        });
    });
}
/* USAGE */
try{
    myFunc(input, function(e, result){
        if(err) // handle operational error. 
        else{
            //continue what ever you need with result
        }
    })
}catch(e){
    //crash gracefully
}

但是,如果我们在基于承诺的方法中编写此代码:

function myFunc (input){
    if(typeof input === 'undefined'){
        throw new Error('Invalid argument');
    }
    return asinc1(input)
    .then(asinc2);
}

/* USAGE */
myFunc(input)
.then(function(result){
    //continue what ever you need with result
}).catch(function(e){
    //handle both - programmatic and operational errors
})

没有办法区分错误类型因此我不知道错误发生时究竟要做什么。

2 个答案:

答案 0 :(得分:2)

我一直在做更多的研究,并找到了两种可能的解决方案。但是我不会对他们100%肯定,所以仍然希望听到其他答案或有人对我的方法发表评论。

有两种选择:

  1. 在创建时将Error对象标记为编程或操作。然后你可以把那个物体冒泡到上杆,然后决定做什么。
  2. 在上部控制杆(来电者)中实施两个捕捉机制
  3. 要实施第一个,我找到了两个好方法。一个是创建custom MyError object,第二个是添加额外的标记:

    if(programmatic error){
      let e = new Error('Message');
      e.isProgrammtic = true;
      throw e;
    }
    

    现在你可以捕获它并传递给全局logger对象,在那里做一个简单的检查是否是一个程序错误并采取相应的行动。

    使用像bluebird这样的promise库可以实现第二个选项。他们有.error method可以捕获明显的操作错误。所以在我的例子中我们可以这样做:

    myFunc(input)
    .then(function(result){
        //continue what ever you need with result
    }).catch(function(e){
        //handle programatic errors. Crash gracefully and restart
    }).error(function(e){
       // handle operational error. Dont crash
    })
    

答案 1 :(得分:-1)

您可以return Promise.reject()代替throw Error

function asinc1() {}

function asinc2() {}

function myFunc(input) {
  if (typeof input === "undefined") {
    return Promise.reject(new Error('Invalid argument'));
  }
  return asinc1(input)
    .then(asinc2);
}

/* USAGE */
myFunc(void 0)
  .then(function(result) {
    //continue what ever you need with result
  }).catch(function(e) {
    //handle both - programmatic and operational errors
    console.log(e)
  })