如何在Node.js中打印堆栈跟踪?


Answers:


615

任何Error对象都具有stack捕获其构造点的成员。

var stack = new Error().stack
console.log( stack )

或更简单地说:

console.trace("Here I am!")

1
或只是sys.puts(new Error().stack)(添加系统模块后)
sirhc 2010年

5
截至目前,sys已被使用。替换为'util'
Pindatjuh 2011年

12
+1同时显示new Error().stack,在您不希望涉及控制台的情况下可以使用。
尤金·别列索夫斯基

1
的优点之一trace是它还显示当前行/上下文,stack而不显示当前行/上下文。如果您想手动创建该行,则该信息位于错误对象中。
studgeek

130
console.log(err.stack)和console.trace()不会给您相同的结果。err.stack提供了err对象本身的堆栈跟踪(以我们通常认为异常的方式起作用),而console.trace()将在调用console.trace()时打印出调用堆栈。因此,如果您发现某个更深层的代码引发了一些错误,console.trace()将不会在堆栈跟踪中包含该更深层的代码,因为该代码不再位于堆栈中。但是,console.log(err.stack)将包含更深的层,只要它抛出Error对象即可。
d512


96

正如已经回答的那样,您可以简单地使用trace命令:

console.trace("I am here");

但是,如果您遇到有关如何记录异常的堆栈跟踪的问题,则只需记录Exception对象即可。

try {  
  // if something unexpected
  throw new Error("Something unexpected has occurred.");     

} catch (e) {
  console.error(e);
}

它将记录:

错误:发生了意外情况。
    在对象的主要位置(c:\ Users \ Me \ Documents \ MyApp \ app.js:9:15)
    。(c:\ Users \ Me \ Documents \ MyApp \ app.js:17:1)
    位于Module._compile(module.js:460:26)
    位于Object.Module._extensions..js(module.js:478:10 )
    在     启动时(node.js
    )
    在Function.Module.runMain(module.js:501:10)
在Function.Module._load(module.js:310:12 )在Module.load(module.js:355:32):129:16),
    位于node.js:814:3


如果您的Node.js版本小于6.0.0,则仅记录Exception对象是不够的。在这种情况下,它将仅打印:

[错误:发生了意外情况。]

对于节点版本<6,请像当前节点版本一样使用console.error(e.stack)而不是console.error(e)打印错误消息以及完整堆栈。


注:如果该异常是作为字符串创建类似throw "myException",它无法获取堆栈跟踪和记录e.stack的产量不确定

为了安全起见,您可以使用

console.error(e.stack || e);

它将适用于新旧版本的Node.js。


不会console.error(e)打印所有e对象,包括e.stack
drmrbrewer

1
@drmrbrewer,感谢您指出这一点。似乎在节点版本4.x和7.x之间行为发生了变化(可能是V8更改)。我已经更新了答案。
Zanon

1
@drmrbrewer确认此行为在版本6.0.0上已更改
Zanon

2
对不起,我刚刚发现了一些至关重要的东西。请参阅我对相关文章的评论:stackoverflow.com/questions/42528677/…。似乎单独记录错误确实显示了错误的全部内容,但是尝试将其(如字符串)与其他文本连接起来将仅导致使用简短消息部分。通过这种实现,这一切都变得更加有意义。
drmrbrewer

1
您保存了我的一天)
Alex

39

Error以更易读的方式在控制台中打印stacktrace :

console.log(ex, ex.stack.split("\n"));

结果示例:

[Error] [ 'Error',
  '    at repl:1:7',
  '    at REPLServer.self.eval (repl.js:110:21)',
  '    at Interface.<anonymous> (repl.js:239:12)',
  '    at Interface.EventEmitter.emit (events.js:95:17)',
  '    at Interface._onLine (readline.js:202:10)',
  '    at Interface._line (readline.js:531:8)',
  '    at Interface._ttyWrite (readline.js:760:14)',
  '    at ReadStream.onkeypress (readline.js:99:10)',
  '    at ReadStream.EventEmitter.emit (events.js:98:17)',
  '    at emitKey (readline.js:1095:12)' ]


5

尝试Error.captureStackTrace(targetObject [,constructorOpt])

const myObj = {};
function c() {
  // pass
}

function b() {
    Error.captureStackTrace(myObj)
    c()
} 

function a() {
    b()
}

a()

console.log(myObj.stack)

函数ab被捕获在错误堆栈中并存储在中myObj


2
如果您希望错误具有stack属性,则在Node> = 6:时需要调用此属性Error.captureStackTrace(error)
cjbarth

请注意,如果您不希望被调用的帧Error.captureStackTrace出现在堆栈跟踪中,则可以通过将其作为constructorOptarg 传递来忽略它。
Ullauri

3

对于我所知无法在nodejs中打印完整的堆栈跟踪信息,您只能打印“部分”堆栈跟踪信息,您看不到代码中的来源以及异常发生的位置。这就是Ryan Dahl在此youtube视频中解释的内容。http://youtu.be/jo_B4LTHi3I ,精确时间为56:30。希望这可以帮助


2
是的,但@Timboudreau的答案中的模块“修复了”
Bogdan D

3

@isaacs答案是正确的,但是如果您需要更具体或更清晰的错误堆栈,则可以使用以下功能:

function getCleanerStack() {
   var err = new Error();
   Error.captureStackTrace(err, getStack);

   return err.stack;
}

此功能直接来自NodeJS中console.trace功能

源代码:最新版本旧版本


1
它不起作用,仅显示当前行的堆栈(不显示发生此错误的行)。err.stack是更正确的答案。
伊恩·钟

2

如果您只想记录错误的堆栈跟踪(而不是错误消息),则节点6及更高版本会自动在堆栈跟踪中包含错误名称和消息,如果要执行一些自定义错误处理,这会有些烦人:

console.log(error.stack.replace(error.message, ''))

此解决方法将仅记录错误名称和堆栈跟踪(因此,例如,您可以设置错误消息的格式并在代码中的其他位置显示该错误消息)。

上面的示例将仅显示错误名称,后跟堆栈跟踪,例如:

Error: 
    at /Users/cfisher/Git/squashed/execProcess.js:6:17
    at ChildProcess.exithandler (child_process.js:213:5)
    at emitTwo (events.js:106:13)
    at ChildProcess.emit (events.js:191:7)
    at maybeClose (internal/child_process.js:877:16)
    at Socket.<anonymous> (internal/child_process.js:334:11)
    at emitOne (events.js:96:13)
    at Socket.emit (events.js:188:7)
    at Pipe._handle.close [as _onclose] (net.js:498:12)

代替:

Error: Error: Command failed: sh ./commands/getBranchCommitCount.sh HEAD
git: 'rev-lists' is not a git command. See 'git --help'.

Did you mean this?
        rev-list

    at /Users/cfisher/Git/squashed/execProcess.js:6:17
    at ChildProcess.exithandler (child_process.js:213:5)
    at emitTwo (events.js:106:13)
    at ChildProcess.emit (events.js:191:7)
    at maybeClose (internal/child_process.js:877:16)
    at Socket.<anonymous> (internal/child_process.js:334:11)
    at emitOne (events.js:96:13)
    at Socket.emit (events.js:188:7)
    at Pipe._handle.close [as _onclose] (net.js:498:12)

1

万一有人像我一样还在寻找它,那么我们可以使用一个称为“ stack-trace”的模块。真的很受欢迎。NPM连结

然后遍历痕迹。

  var stackTrace = require('stack-trace');
  .
  .
  .
  var trace = stackTrace.get();
  trace.map(function (item){ 
    console.log(new Date().toUTCString() + ' : ' +  item.toString() );  
  });

或者只是简单地打印跟踪:

var stackTrace = require('stack-trace');
.
.
.
var trace = stackTrace.get();
trace.toString();

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.