Javascript 如何使用node.js中的堆栈跟踪来console.log错误?

Javascript 如何使用node.js中的堆栈跟踪来console.log错误?,javascript,node.js,error-handling,console.log,Javascript,Node.js,Error Handling,Console.log,我一直在尝试调试我的节点应用程序,以便在我的日志中找到错误的来源,该错误只显示为“错误:发送后无法设置头””,没有跟踪信息或任何上下文 碰巧,我想我现在已经解决了这个问题。。。我正在使用并且正在继续处理传递给异步网络操作的回调,该回调最终将尝试执行res.send(),尽管req.timedout在网络操作期间已通过connect timeout设置为“true” 但我仍然无法理解为什么我的日志没有显示此错误的跟踪信息。在我的代码中返回错误的任何地方,我都会使用以下命令将其记录到控制台: con

我一直在尝试调试我的节点应用程序,以便在我的日志中找到错误的来源,该错误只显示为“
错误:发送后无法设置头”
”,没有跟踪信息或任何上下文

碰巧,我想我现在已经解决了这个问题。。。我正在使用并且正在继续处理传递给异步网络操作的回调,该回调最终将尝试执行
res.send()
,尽管
req.timedout
在网络操作期间已通过
connect timeout
设置为“true”

但我仍然无法理解为什么我的日志没有显示此错误的跟踪信息。在我的代码中返回错误的任何地方,我都会使用以下命令将其记录到控制台:

console.log(err);
如果
err
对象中有可用的跟踪信息,并且这些信息似乎放在
err.stack
中,那么上面的语句不应该将
err
的全部内容(包括
err.stack
)转储到控制台日志中吗?我的理解是,与以下情况相比,我不会因为执行上述操作而丢失任何信息:

console.log(err.stack);
但类似的帖子似乎提出了不同的建议(尽管链接帖子现在已经更新)

我实际上更进一步,添加了一些相关文本以帮助定位错误:

console.log('error in dodgyFunction:', err);
但尽管如此,我仍然只得到“
错误:发送后无法设置头文件”
”,没有任何上下文。这是否是因为此控制台错误消息是在外部库(如
express
)中输出的?我认为外部库应该将错误发送回主代码,以便进行相应的处理

编辑:下面是一个示例,我将错误和超时检查放在传递给异步操作的回调函数的顶部:

var execFile = require('child_process').execFile;
execFile('dodgycommand', options, function(error, stdout, stderr) {
    if (req.timedout) {
        console.log('timeout detected whilst running dodgycommand, so aborting...');
        return;
    }
    if (error) {
        console.log('error running dodgycommand:', error);
        res.sendStatus(400);
        return;
    }

    // ... it's safe to continue ...

}

我基本上一直遵循相同的模式。

您的模式看起来普遍很普通,但我会说,作为一个规则,我不喜欢它,稍后再详细介绍

至于你的主要问题,根据你所提供的,很难回答。如果您显示的是实际的代码,而不是“我通常遵循此模式”,这可能会有所帮助。但同样可能的是,错误被抛出了您不期望的地方,因此您的
console.log
根本没有被调用

看起来你在寻找最佳实践,所以我会给你我认为目前为止最好的

首先,不要使用
console.log
进行日志记录。这并不可怕,但你可以做得更好。我最喜欢的是用作记录请求信息和应用程序日志的中间件

使用
debug
可以设置自定义日志级别,并以所需的粒度级别监听所需的任何级别。这一切都是通过设置调试环境变量来控制的,在生产环境中,您可以重定向到文件或任何其他目标。此外,许多节点模块(包括Express和Connect)使用Debug作为其后台日志记录程序,因此通过调整调试变量,您可以根据需要查看其内部日志记录的多少。对于找出哪里出了问题非常有用

第二,正如我所说的,当涉及到路由时,我根本不使用您拥有的模式。我发现,如果我不小心的话,很容易意外地多次发送头,因此我的中间件总是返回
next()
,并且只在实际的处理程序中发送响应,我可以确保只发送一次。当遇到错误时,我总是传递
next(e)
,然后我可以在错误处理函数中处理它。我还创建了该库,以提供基于web状态代码的标准错误和通用错误处理程序

该模式如下所示:

// middleware function to put something on the request object
app.use((req, res, next) => {
  MyModel.doSomething((e, thing) => {
    if (e) return next(e);
    if (!thing) return next(new NotFound()); // NotFound is an error in praeter that equates to a 404. 
    req.thing = thing;
    return next();
  });
});
后来

// log in here is a reference to my debug configured log object
app.use((err, req, res, next) => {
  log.error(err);
  log.error(err.stack);
  return res.status(err.statusCode || 500).send(err.message)
});
注意,这是一个简单的最终错误处理程序示例。根据应用程序的需要,我经常会有几个这样的错误代码,我可能会以不同的方式处理不同的错误代码

我现在已安装,我可以确认以下内容:

节点4.0.0

使用
console.log(err)
仅打印错误消息

节点7.7.0(最新版本)

使用
console.log(err)
打印错误消息和完整堆栈



我已确认此行为在版本6.0.0上发生了更改。因此,如果您使用较旧的版本,我建议您更新Node.js或使用
console.log(err.stack)
来打印整个堆栈。

我刚刚了解了发生的情况,我希望这将帮助其他人避免这个初学者的错误

对于我的一些错误日志记录,我使用了如下类似的方法,使用字符串连接来构造错误消息:

console.log('error in function abc: ' + err + ' whilst doing xyz');
而在其他地方,我使用了类似于以下的方法,只是将错误消息的片段作为单独的参数传递给
console.log

console.log('error in function xyz:', err, 'whilst doing abc');
我现在看到这些会产生不同的结果

前者必须字符串化
err
,以便它可以与消息的其他部分连接,并且根据,在这样做时,它只使用消息部分

但是,在后一种形式中,
err
对象必须由
console.log
完整地处理,并作为一个整体转储

这就解释了为什么有时我没有看到错误的全部内容,正如我所预料的那样,而有时我看到了错误的全部内容


至于其他库放在那里的控制台日志消息,还需要检查的是,您没有在日志查看器中过滤出日志消息的“堆栈”部分。。。原来我是(为了节省日志配额…我正在使用书面记录)。。。哦。我是通过过滤掉以
\uuuuuuuuuuu at
开头的任何行(四个空格后跟'at'),例如
\uuuuuuu-at-Request.self.callback

您的
控制台.log()
语句放在哪里?@JyotmanSingh我已经更新了我的