2012-12-08 49 views
2

如果我拋出一個錯誤,express使用connect errorHandler中間件很好地呈現它。當我在承諾中拋出錯誤時,它將被忽略(這對我來說很有意義)。但是,如果我在promise中拋出一個錯誤,並且調用「done」節點崩潰,因爲該異常沒有被中間件捕獲。表達錯誤中間件不處理promise.done()拋出的錯誤

exports.list = function(req, res){ 
    Q = require('q'); 
    Q.fcall(function(){ 
    throw new Error('asdf'); 
    }).done(); 
    res.send("This prints. done() must not be throwing."); 
}; 

與此輸出運行上面,節點崩潰後:

node.js:201 
     throw e; // process.nextTick error, or 'error' event on first tick 
      ^
Error: asdf 
    at /path/to/demo/routes/user.js:9:11 

所以,我的結論是()完成不拋出異常,但會導致異常被拋出別處。是對的嗎?有沒有辦法完成我正在嘗試的 - 承諾中的錯誤將由中間件來處理?這個黑客將捕獲頂層的異常,但它不在中間件領域,所以不適合我的需要(很好地呈現錯誤)。

//in app.js #configure 
process.on('uncaughtException', function(error) { 
    console.log('uncaught expection: ' + error); 
}) 

回答

2

也許你會發現connect-domain中間件可用於處理異步錯誤。這個中間件允許你像常規錯誤一樣處理異步錯誤。

var 
    connect = require('connect'), 
    connectDomain = require('connect-domain'); 

var app = connect() 
    .use(connectDomain()) 
    .use(function(req, res){ 
     process.nextTick(function() { 
      // This async error will be handled by connect-domain middleware 
      throw new Error('Async error'); 
      res.end('Hello world!'); 
     }); 
    }) 
    .use(function(err, req, res, next) { 
     res.end(err.message); 
    }); 

app.listen(3131); 
+0

對於我來說,困難的部分只是理解nodejs的事件循環與我認爲理所當然的事情不兼容。領域模塊似乎已經被引入以某種方式解決這個問題。謝謝! http://nodejs.org/api/domain.html – mkirk