当我的代码在堆栈跟踪中没有任何地方时,如何调试node.js错误?

时间:2016-07-26 19:01:08

标签: node.js express

实际上,我并不完全理解为什么我的代码不在堆栈跟踪中,如果node是单线程的。也许我从根本上误解了一些问题,但是为什么我的应用程序有时会因为堆栈跟踪没有我写的任何东西而死?

我正在使用node / express编写一个非常简单的代理服务器。举个例子,我经常得到这个“socket hangup error”:

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') {...}

5 个答案:

答案 0 :(得分:9)

某些错误(如您提到的错误)不是由您的代码引起的。实际上,它是由应用程序中缺少代码引起的。 (例如,您的应用程序代码可能缺少正常处理ECONNRESET的代码,即远程套接字断开。

现在,关于如何调试此类错误(包括第三方代码)的问题。当然,您可以使用堆栈跟踪和longjohn等。

但是,对我来说,更容易& 更快解决方案是使用--inspect选项以调试模式运行应用程序,使用 Chrome调试程序进行检查(无断点),启用暂停例外选项。这就是你需要做的一切。现在,只要有异常,chrome调试器就会将应用程序暂停在引发异常的行。使找到这样的错误变得容易得多。

Pause On Exception

希望这能帮到你!

答案 1 :(得分: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

答案 2 :(得分:3)

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

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

因此,如果A()包含在try中并捕获所有内部异常,则会被捕获。

但是在Async环境中,回调函数在调用函数之外执行:

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

这里函数A调用async函数B(通常是一个库),回调函数C作为参数,函数B在完成node.js调用函数I之后启动一个异步任务,这是函数的内部函数库和它调用函数C.在这里你看到 C D 在你的代码之外被调用。

因此,有两件事需要考虑:

1-你必须在try和catch中包装你的回调函数代码。

2-在函数I中可能存在异常,您无法捕获代码。这些是您所指的异常,其中堆栈跟踪中的所有javascript文件都不属于您,因为它们未在您的代码中启动。

现在,如果函数B (它的库)写得很好,它必须提供一些方法来捕获这些异常。其中一个是on('error', cb)。因此,您应该始终查看库文档,以了解如何捕获和处理此类异常。

如果库写得不好并且没有提供任何内容来捕获代码中的异常,那么可以使用像chrome inspector或WebStorm调试器这样的调试器来捕获它们,但除了操作其源代码之外别无他法,所以至少它们被绕过你的代码,或者你可以提交错误报告。

Node.js还提供了一个未捕获的异常处理程序,它可以捕获所有未捕获的异常:

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

虽然在此之后继续执行会有风险,因为事情可能处于不确定的状态,但它是记录错误的好地方。

答案 3 :(得分:2)

Stack Trace不包含您的文件,因为这种类型的错误是由服务器连接问题创建的:

主机超时

.cart-btn {
        width: 120px;
        height: 40px;
        display: inline-block;
        background-color: #292c2e;
        margin-left: 10px;
}

控制台输出

[ 'code' ]
e.code => ECONNRESET

当服务器意外终止连接或未发送响应时。

有关详细信息,请查看node app error codes

或参考此issue

答案 4 :(得分:1)

您可以尝试node.js的内置调试器。此调试器允许您单步执行不属于您的代码。

node debug script.js

另一个好工具是node-inspector

本文提供了一些其他调试选项,可用于确定异常原因:How do I debug Node.js applications?