当我的代码在堆栈跟踪中无处可查时,如何debuggingnode.js错误?

实际上,如果节点是单线程的,我不完全理解为什么我的代码不在堆栈跟踪中。 也许我从根本上误解了一些东西,但是为什么我的应用程序有时会死掉一个堆栈跟踪,这个堆栈跟踪没有我写的东西?

我正在写一个非常简单的代理服务器使用节点/快递。 作为一个例子,我定期得到这个“套接字挂断错误”:

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风格error handling程序,直到我find正确的地方。

我觉得我从根本上失去了一些东西 – 我应该做什么不同的debugging这样的错误? 如果我无法看到(在我的代码中)导致它,我怎么知道在哪里处理它? 我怎么知道我是否应该使用try / catch块,或者像request.on('error') {...}

一些错误,如你所提到的,不是由你的代码造成的。 实际上,这是由于应用程序中缺less代码而造成的。 (例如,您的应用程序代码可能缺less正确处理ECONNRESET(即远程套接字断开连接)的代码。

现在,对于如何debugging这种错误(包括第三方代码)的问题。 当然,你可以使用堆栈跟踪和longjohn等

但是,对我来说, 更简单 快捷的解决scheme是使用–inspect选项以debugging模式运行应用程序,使用Chromedebugging器检查它( 没有断点 ),启用“ 暂停exception”选项。 这就是你需要做的。 现在,每当出现exception时,chromedebugging器都会将该应用程序正好停在抛出exception的那一行。 使它更容易find这样的错误。

暂停例外

希望这可以帮助你!

你可以做一些类似的debugging这样的错误。

 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 

与您的假设相反,node.js的单线程范例会导致这些types的错误。 在像java这样的multithreading环境中,所有被调用的函数都在调用者函数中执行:

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

所以如果A()被包装在一个try中,并捕获所有的内部exception。

但是在asynchronous环境中,callback函数在调用者函数之外执行:

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

这里函数A调用asynchronous函数B(通常是一个库),以callback函数C为参数,函数B在完成后启动一个asynchronous任务node.js调用函数I,该函数是库的一个内部函数,调用函数C.在这里你看到我的 CD在你的代码之外被调用。

所以这里有两点需要考虑:

1-你必须包装你的callback函数代码。

2-在函数I中可能有一个例外,你不能在代码中捕捉到这个例外。 这些就是你所指的那些堆栈跟踪中的javascript文件都不属于你的例外,因为它不是在你的代码中启动的。

现在,如果函数B (它的库)写得很好,它必须提供一些方法来捕获这些exception。 其中一个on('error', cb) 。 所以你应该总是检查图书馆文件,看看你如何捕捉和处理这种例外。

如果库编写得不好,没有提供任何代码来捕获它的exception,你可以使用一个debugging器,如铬检查器或WebStormdebugging器来捕获它们,但除了处理它的源代码外,没有别的办法,至less它们被绕过你的代码,或者你可以提交一个错误报告。

Node.js还提供一个捕获所有未捕获的exception的未捕获的exception处理程序:

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

尽pipe在这之后继续执行是有风险的,因为事情可能处于不确定的状态,但是这是logging错误的好地方。

堆栈跟踪不包含您的文件,因为这种types的错误是创build服务器连接的问题,如:

主机超时

 [ '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' } 

或者服务器意外终止连接或不发送响应。

欲了解更多信息,请查看节点应用程序错

或者引用这个问题 。

您可以尝试使用node.js的内置debugging器。 这个debugging器允许你逐步浏览不属于你的代码。

 node debug script.js 

另一个好工具是节点检查器 。

这篇文章有一些其他的debugging选项,可以用于确定exception的原因: 如何debuggingNode.js应用程序?