节点:当抛出错误未捕获异常时,async.foreach以静默方式失败

时间:2012-10-11 10:48:14

标签: node.js asynchronous error-handling promise

我正在async.forEach构造中包装一些异步执行的'child'函数(来自伟大的lib:https://github.com/caolan/async

当其中一个子函数因未捕获的异常而失败时,整个节点进程将挂起。 (因为回调永远不会返回到async.forEach构造,async.forEach仍然认为子函数正忙)

但是我会想到至少抛出的异常会冒出来,因为我没有把它抓到任何地方。有没有办法配置async.forEach如何处理这些异常?对此编程真的很难。

1 个答案:

答案 0 :(得分:1)

解决。供将来参考:

好的,所以我基本上有这个:

var async = require("async");
var cb = function(){
   //denote done to async.foreach
}
async.forEach(defaultFunctions,function(defaultFunc,cb){   
  defaultFunc(cb);
},callback);

问题在于当某个defaultFunction抛出未捕获的异常时,async.forEach会吞下该异常。而且在调用上下文中无法捕获它。

结果很严重:完全停止父节点进程,没有任何恍惚导致它的原因。

在被调用的上下文中(即:抛出异常的defaultFunction)我当然可以仔细地尝试捕获所有异常,但这些函数是可热插拔的,最终可能有数百个,我不想要通过100%全面的错误处理来加重这些功能。

我找到的解决方案是使用promises(使用Q库 - > github.com/kriskowal/q)将函数包装在:

var async = require("async")
var Q = require("q");
var cb = function(){
   //denote done to async.foreach
}
async.forEach(defaultFunctions,function(defaultFunc,cb){   
  var obj = {
    defaultFunc: defaultFunc
  } 
  return Q.ncall(obj.defaultFunc,obj)
    .then(function(result){
       return cb() ;
    }fail(function(err){
       return cb(err); //ANY thrown uncaught error in obj.defaultFunc will get 
                       //caught and changed to a correct callback as needed
                       //for async.forEach
    }
},callback);

当然,现在我意识到async.foreach可以用Q.promises来完成,但这是另一个故事......