2012-11-10 86 views
11

我對Node.js的和快速的應用程序。我需要爲它編寫測試。我在處理Express應用程序錯誤時遇到問題。我發現這個How do I catch node.js/express server errors like EADDRINUSE?,但它不爲我工作,我不知道爲什麼。我想處理錯誤,它可以同時expressApp.listen發生()正在執行(EADDRINUSE,EACCES等)。的Node.js應用程序快速啓動手柄錯誤

express = require('express') 
listener = express() 

#doesn't work for me 
listener.on('uncaughtException', (err) -> 
    #do something 
) 

#doesn't work too 
listener.on("error", (err) -> 
    #do something 
) 

#this works, but it caughts all errors in process, I want only in listener 
process.on('uncaughtException', (err) -> 
    #do something 
) 

listener.listen(80) #for example 80 to get error 

任何想法?

+0

'listener.on '錯誤',...'應該工作。它是否只是執行正常的堆棧跟蹤和崩潰,即使該線路在那裏? – loganfsmyth

+0

是的,如果我這樣做'listener.listen(80)' 它打印堆棧跟蹤和崩潰。即使有'listener.on'錯誤',...' 在這種情況下可能發生的錯誤不是表達錯誤,這就是它無法處理的原因。但這只是假設。 –

回答

20

首先,expressJS不扔uncaughtException事件,過程呢,所以一點也不奇怪,你的代碼不起作用。

所以使用方法:process.on('uncaughtException',handler)代替。

接着,expressJS已經提供的錯誤處理,這是使用中間件功能提供用於此目的的,如在標準的手段:

app.configure(function(){ 
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
}); 

該函數返回一個錯誤消息到客戶端,具有可選堆棧跟蹤,並在connectJS errorHandler記錄。

(注意的ErrorHandler實際上是connectJS的一部分,只有expressJS曝光。)

如果現有的ErrorHandler提供了行爲不足以滿足您的需求,它的源位於connectJS's errorHandler middleware,可以很容易地修改以滿足您的需求。

當然,而不是直接修改該功能,「正確」的方式做,這是創建自己的ErrorHandler,使用connectJS版本作爲起點,如:

var myErrorHandler = function(err, req, res, next){ 
    ... 
    // note, using the typical middleware pattern, we'd call next() here, but 
    // since this handler is a "provider", i.e. it terminates the request, we 
    // do not. 
}; 

並安裝成expressJS爲:

app.configure(function(){ 
    app.use(myErrorHandler); 
}); 

filterprovider中間件和How To Write Middleware for Connect/Express connectJS的想法的一個精心編寫的教程中的說明,請參見Just Connect it, Already

您也可能會發現這些有用:

最後的信息關於測試expressJS的極好來源可以its own tests.

+0

+1,很好徹底的回答! – Menztrual

+0

感謝您的詳細解釋,無論如何,這將是有用的。 在處理Web請求時,我不需要處理錯誤。我需要創建服務器並調用app.listen(...)。現在我明白了,在這裏需要Node.js錯誤處理,而不是Express中的中間件。 process.on('uncaughtException',處理程序)在我的情況下是可以接受的。 –

+0

@Piane_Ramso,那麼是的,將你自己的事件處理程序添加到'process.on('uncaughtException')'肯定是要走的路。如果你很好奇,處理位於[node.cc](https://github.com/joyent/node/blob/master/src/)中第1739行(或附近)的「未捕獲」異常的底層代碼node.cc) –

57
被發現

這應該做的伎倆:

listener.listen(80).on('error', function(err) { }); 

什麼listener.listen實際上做的是創建一個HTTP服務器和調用它聽:

app.listen = function(){ 
    var server = http.createServer(this); 
    return server.listen.apply(server, arguments); 
}; 
+10

這是令人難以置信的,這是最簡單和正確的答案,它沒有upvotes! 訣竅是瞭解webServer對象由app.listen返回。我用這個: '''app.listen(80,函數(){ 的console.log( '成功'); })上( '錯誤',函數(ERR){ 如果(err.errno === 'EADDRINUSE'){ 的console.log( '端口忙碌'); }否則{ 的console.log(ERR); } }); ''' –

+0

我不明白你的代碼在做什麼。如果你打電話app.listen節點已經做了一個http.createServer下我想,或者你基本上重寫原生app.listen()方法並用它自己的代碼覆蓋它? – PositiveGuy

+0

代碼的第一行是應該使用的內容,其他所有內容都是解釋爲什麼會起作用。 –