2012-10-11 25 views
2

我包裹在async.forEach構建執行「child'函數一些異步(從大的lib:https://github.com/caolan/async節點:async.foreach默默地失敗時的錯誤是未捕獲的異常被拋出

當一個這些子函數失敗,整個節點進程掛起一個未捕獲的異常。 (因爲回調永遠不會返回到async.forEach結構,async.forEach仍然認爲子功能很忙)

但是我會認爲至少拋出的異常會起泡,因爲我沒有捕獲它隨處可見。有沒有辦法配置async.forEach如何處理這些異常?這是很難編程的。

+0

你的代碼是什麼樣的?什麼引發這個異常? (你的代碼,或其他一些模塊) –

+0

我更一般地問。關鍵是這些子功能可以以某種CMS時尚方式進行熱插拔/交換。從技術上講,我可以將這些子函數中調用的客戶端代碼封裝在try/catch-blocks中,並自行返回適當的回調(err)等。但是,在定義這些函數時,我不希望自己關心錯誤處理等問題,只是功能流。這種功能中的偶然錯誤不應該阻止整個系統。相反,我想(經嚴格測試)基礎結構調用配置的函數來處理拋出的錯誤。 –

+0

不知道我的解釋是否清楚。無論如何,我遇到過Q(https://github.com/kriskowal/q),它基於承諾而不是回調。它看起來像一個記錄良好的功能,可以將拋出的異常自動轉換爲(在諾言中)promise.rejections。將100%的「孩子」功能解放出來需要正確地捕捉所有錯誤。 –

回答

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%全面的錯誤處理來加載這些功能。

我找到了一個解決方案是使用承諾(使用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); 

當然,現在我實現異步。 foreach可以用Q.promises代替,但這是另一回事......

+2

奇怪。我無法用一個簡單的例子重現異步問題,其中一個'defaultFunctions'引發異常。另外,爲什麼不使用'async.parallel(defaultFunctions,cb);'而不是'forEach'? – JohnnyHK

+0

嗯,真的很奇怪..至於'forEach',這是立即通過快速瀏覽示例立即解決的方法。我現在意識到「並行」會同樣有效。我將重構/測試'parallel'是否存在我遇到的問題。 –

相關問題