【问题标题】:Node: async.foreach fails silently when error is uncaught exception is thrown节点:当错误未捕获时,async.foreach 静默失败,抛出异常
【发布时间】:2012-10-02 00:23:07
【问题描述】:

我将一些异步执行的“子”函数包装在 async.forEach 构造中(来自伟大的库:https://github.com/caolan/async

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

但是我认为至少抛出的异常会冒泡,因为我没有在任何地方捕获它。有没有办法配置 async.forEach 如何处理这些异常?对此进行编程真的很困难。

【问题讨论】:

  • 你的代码是什么样的?是什么引发了这个异常? (您的代码或其他模块)
  • 我更笼统地问。关键是这些子功能可以以某种 CMS 方式进行热插拔/交换。从技术上讲,我可以将在这些子函数中调用的客户端代码包装在 try/catch 块中并自己返回正确的回调(错误)等。但是在定义这些函数时,我不想让自己担心错误处理等,只是功能流程。此类功能中的偶然错误不应停止整个系统。相反,我希望(经过大量测试的)基础设施调用配置的函数来处理抛出的错误。
  • 不确定我的解释是否清楚。无论如何,我遇到了基于承诺而不是回调的 Q (github.com/kriskowal/q)。它看起来像是一个有据可查的特性,抛出的异常可以自动转换为(用 promise 说话)promise.rejections。将“子”函数从 100% 正确捕获所有错误的需要中解放出来。
  • async.series 相同的问题。未捕获的异常会默默地终止进程。您使用 Q 的解决方法效果很好。

标签: node.js asynchronous error-handling promise


【解决方案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% 完全防错的错误处理来负担这些功能中的每一个。

我发现的一个解决方案是使用 Promise(使用 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 轻松完成,但这是另一回事...

【讨论】:

  • 很奇怪。我无法通过一个简单的示例重现异步问题,其中defaultFunctions 之一引发异常。还有,你为什么不用async.parallel(defaultFunctions, cb); 而不是forEach
  • hmmm,确实很奇怪.. 至于forEach,这是通过快速浏览示例立即解决的方法。我现在意识到parallel 会同样有效。如果parallel 没有我遇到的问题,我将重构/测试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-19
  • 1970-01-01
  • 2013-05-07
  • 1970-01-01
  • 1970-01-01
  • 2020-09-28
  • 1970-01-01
相关资源
最近更新 更多