2016-07-26 26 views
12

而實際上,我並不完全理解爲什麼我的代碼不在堆棧跟蹤中,如果節點是單線程的。也許我從根本上誤解了某些東西,但爲什麼我的應用程序有時會死亡,並且沒有任何我寫過的堆棧跟蹤?當我的代碼無處堆棧跟蹤時,如何調試node.js錯誤?

我正在用node/express寫一個非常簡單的代理服務器。舉個例子,我定期收到這個「窩掛斷錯誤」:

Error: socket hang up 
at createHangUpError (_http_client.js:250:15) 
at Socket.socketOnEnd (_http_client.js:342:23) 
at emitNone (events.js:91:20) 
at Socket.emit (events.js:185:7) 
at endReadableNT (_stream_readable.js:926:12) 
at _combinedTickCallback (internal/process/next_tick.js:74:11) 
at process._tickCallback (internal/process/next_tick.js:98:9) code: 'ECONNRESET' } 

而且因爲沒有在堆棧跟蹤JavaScript文件的是我的,我完全不知道這是來自哪裏。這基本上是試驗和錯誤,試圖捕捉錯誤並添加.on風格的錯誤處理程序,直到找到正確的位置。

我覺得我從根本上失去了一些東西 - 爲了調試這樣的錯誤,我應該做些什麼改變?如果我無法看到(在我的代碼中)導致它的怎麼辦?我怎麼知道我是否應該使用try/catch塊,或者類似request.on('error') {...}

+0

http://stackoverflow.com/search?q=express+socket+hang+up –

+0

你可以試試使用類似[longjohn](https://www.npmjs.com/package/longjohn)的方法,它會嘗試在異步邊界('setTimeout','process.nextTick'等等)上維護堆棧跟蹤。雖然你應該避免在生產中使用它,因爲它會影響性能。 – idbehold

+0

請分享代碼? – 1Mayur

回答

8

一些錯誤,如您所提到的錯誤,並不是由您的代碼造成的。實際上,這是由於您的應用程序中沒有代碼而造成的。 (例如,您的應用程序代碼可能缺少用於正確處理ECONNRESET的代碼,即遠程套接字斷開。

現在,您可以調試有關如何調試此類錯誤(包括第三方代碼)的問題。當然,您可以使用堆棧跟蹤和longjohn

但是,對我來說,更容易 & 更快解決方案是用--inspect選項運行在調試模式下的應用程序,與鉻調試檢查它(沒有斷點 ),與暫停例外選項啓用。這就是你需要做的。現在,無論何時出現異常,chrome調試器都會將該應用程序正好暫停在拋出異常的那一行。使它更容易找到這樣的錯誤。

Pause On Exception

希望這可以幫助你!

2

與您的假設相反,node.js的單線程範例會導致這些類型的錯誤。在多線程環境下,如Java中,所有被調用函數被調用方函數內部執行:

java -> A -> B -> C -> D 

因此,如果A()被包裹在一個嘗試,抓住所有的內部異常引起。

但在異步環境下,回調函數被調用者函數外執行:

node -> A -> B(C) 
node -> I -> C -> D 

在這裏,函數的調用異步函數B(一般的庫)與回調函數C作爲一個參數,函數B開始完成後的異步任務node.js調用函數I,該函數是該庫的內部函數,並調用函數C.這裏你可以看到Çd被稱爲你的代碼之外。

所以這裏要考慮兩件事情:

1,必須用你的回調函數的代碼在try和catch。

2 - 有可能是在功能例外,我,你不能在你的代碼趕上。這些是你所指的那些例外,堆棧跟蹤中的JavaScript文件都不是你的,因爲它不是在你的代碼中啓動的。

現在,如果函數B(其庫)寫得很好,它必須提供一些方法來捕獲這些異常。其中之一將是on('error', cb)。所以你應該總是檢查圖書館文件,看看你如何能夠捕捉和處理這種例外情況。

如果庫編寫得不好,並且沒有提供任何代碼來捕獲代碼中的異常,則可以使用像Chrome檢查器或WebStorm調試器這樣的調試器來捕獲它們,但除了操作其源代碼之外沒有別的辦法他們被繞過你的代碼,或者你可以提交一個錯誤報告。

的Node.js也提供捕捉所有捕獲的異常未捕獲的異常處理程序:

process.on('uncaughtException', (err) => { 
    process.exit(1); 
}); 

雖然它的風險在這裏後繼續執行,因爲事情可能會在一個不確定的狀態,但它是記錄的好地方錯誤。

2

堆棧跟蹤不包含您的文件,因爲這種類型的錯誤創建服務器連接的問題,如:

主機超時

[ 'code' ] 
e.code => ECONNRESET 

控制檯輸出

{ Error: socket hang up 
    at createHangUpError (_http_client.js:250:15) 
    at TLSSocket.socketCloseListener (_http_client.js:282:23) 
    at emitOne (events.js:101:20) 
    at TLSSocket.emit (events.js:188:7) 
    at TCP._handle.close [as _onclose] (net.js:492:12) code: 'ECONNRESET' } 

OR當服務器意外終止連接或不發送re sponse。

欲瞭解更多信息檢查node app error codes

或涉及本issue

4

你可以做一些類似的調試這樣的錯誤。

process.on('uncaughtException', function(err) { 
    console.log(err.stack); 
    throw err; 
}); 

您還可以增加堆棧跟蹤大小限制和/或堆棧大小。

node --stack_trace_limit=200 app.js //defaults to 10 
node --stack-size=1024 app.js // defaults to 492kB 
1

您可能會嘗試爲node.js內置的調試器。該調試器允許您逐步瀏覽不屬於您的代碼。

node debug script.js 

另一個好工具是node-inspector

這篇文章有可能決定你的異常的原因是有用的一些其他的調試選項:How do I debug Node.js applications?