Como imprimir um rastreamento de pilha no Node.js?

517

Alguém sabe como imprimir um rastreamento de pilha no Node.js?

mike.toString
fonte

Respostas:

615

Qualquer Errorobjeto tem um stackmembro que intercepta o ponto em que foi construído.

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

ou mais simplesmente:

console.trace("Here I am!")
isaacs
fonte
1
ou apenas sys.puts(new Error().stack)(depois de adicionar o módulo do sistema)
Sirhc
5
A partir de agora, o sistema está privado. É substituído por 'util'.
Pindatjuh
12
+1 para mostrar também new Error().stack, o que funciona nos casos em que você não deseja envolver o console.
Eugene Beresovsky
1
Uma vantagem tracedisso é que mostra também a linha / contexto atual que stacknão. As informações estão no objeto de erro, se você quiser criar manualmente essa linha, eu acho.
studgeek
130
console.log (err.stack) e console.trace () não fornecem os mesmos resultados. Enquanto err.stack fornece o rastreamento da pilha para o próprio objeto err (funcionando da maneira que todos pensamos em exceções), console.trace () imprime a pilha de chamadas no ponto em que console.trace () está sendo chamado. Portanto, se você detectar algum erro causado por uma camada mais profunda do código, console.trace () não conterá esse código de camada mais profunda no rastreamento da pilha, pois esse código não está mais na pilha. No entanto, console.log (err.stack) conterá as camadas mais profundas, desde que tenha lançado um objeto Error.
d512 21/02
200

Agora há uma função dedicada no console para isso:

console.trace()
Mariusz Nowak
fonte
11
Apenas certifique-se de prestar atenção ao comentário acima sobre console.trace().
Qix - MONICA FOI ERRADA
5
Por padrão isso só vai mostrar 10 quadros, você pode usar o argumento de linha de comando para aumentar este, por exemplo--stack_trace_limit=200
Michael
E se você deseja gerar um arquivo de log?
Ya.
Isso não parece funcionar com promessas e assíncronas / aguardam, funciona?
bluenote10 5/04
97

Como já respondido, você pode simplesmente usar o comando trace :

console.trace("I am here");

No entanto, se você chegou a essa pergunta pesquisando sobre como registrar o rastreamento de pilha de uma exceção , pode simplesmente registrar o objeto Exception.

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

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

Ele registrará:

Erro: ocorreu algo inesperado.
    em main (c: \ Users \ Me \ Documents \ MyApp \ app.js: 9: 15)
    em Object. (c: \ Users \ Me \ Documents \ MyApp \ app.js: 17: 1)
    em Module._compile (module.js: 460: 26)
    em Object.Module._extensions..js (module.js: 478: 10 )
    em Module.load (module.js: 355: 32)
    em Function.Module._load (module.js: 310: 12)
    em Function.Module.runMain (module.js: 501: 10)
    na inicialização (node.js : 129: 16)
    em node.js: 814: 3


Se sua versão do Node.js for <6.0.0 , o log do objeto Exception não será suficiente. Nesse caso, ele imprimirá apenas:

[Erro: ocorreu algo inesperado.]

Para a versão do nó <6, use em console.error(e.stack)vez de console.error(e)imprimir a mensagem de erro mais a pilha completa, como a versão atual do nó.


Nota: se a exceção for criada como uma sequência de caracteres throw "myException", não será possível recuperar o rastreamento da pilha e o registro e.stackproduzirá indefinidamente .

Para estar seguro, você pode usar

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

e funcionará para versões antigas e novas do Node.js.

Zanon
fonte
Não console.error(e)imprimirá tudo no eobjeto, inclusive e.stack?
Drmrbrewer
1
@drmrbrewer, obrigado por apontar isso. Parece que o comportamento mudou entre as versões do nó 4.xe 7.x (provavelmente uma alteração na V8). Eu atualizei minha resposta.
Zanon
1
@drmrbrewer confirmou que esse comportamento mudou na versão 6.0.0
Zanon
2
desculpe, eu acabei de descobrir algo crucial. Veja meu comentário na postagem relacionada: stackoverflow.com/questions/42528677/… . Parece que o registro do erro por si só mostra, de fato, todo o conteúdo do erro, mas tentar concatená-lo (como uma string) com outro texto fará com que apenas a parte da breve mensagem seja usada. Tudo faz muito mais sentido com essa realização.
Drmrbrewer 02/03
1
você salvar meu dia)
Alex
39

Para imprimir o rastreamento de pilha Errorno console de maneira mais legível:

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

Resultado de exemplo:

[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)' ]
ruX
fonte
5

Tente Error.captureStackTrace (targetObject [, constructorOpt]) .

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

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

function a() {
    b()
}

a()

console.log(myObj.stack)

A função ae bsão capturados na pilha de erros e armazenados em myObj.

Zheeeng
fonte
2
Se você quiser um erro de ter uma stackpropriedade, você precisa chamar isso se Node> = 6: Error.captureStackTrace(error).
Cjbarth 27/08/19
Observe que, se você não deseja que o quadro que ligou Error.captureStackTraceseja exibido no rastreamento da pilha, você pode omiti-lo passando-o como o constructorOptarg.
Ullauri
3

Pelo que sei, não é possível imprimir o rastreamento completo da pilha no nodejs, basta imprimir um rastreamento "parcial" da pilha, não é possível ver de onde você veio no código, apenas onde ocorre a exceção. Isso é o que Ryan Dahl explica neste vídeo do youtube. http://youtu.be/jo_B4LTHi3I no min 56:30 por ser preciso. Espero que isto ajude

ElHacker
fonte
2
verdade, mas o módulo na resposta de @ Timboudreau "corrige" isso #
Bogdan D
3

A resposta do @isaacs está correta, mas se você precisar de uma pilha de erros mais específica ou mais limpa , poderá usar esta função:

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

   return err.stack;
}

Essa função é inspirada diretamente na console.tracefunção em NodeJS .

Código fonte: versão recente ou versão antiga .

Tentáculos Lula Molusco
fonte
1
não funciona, apenas mostra a pilha da linha atual (não a linha em que esse erro ocorreu). err.stacké a resposta mais correta.
Ian Zhong
2

Se você deseja registrar apenas o rastreamento de pilha do erro (e não a mensagem de erro), o nó 6 e superior incluem automaticamente o nome e a mensagem do erro dentro do rastreamento de pilha, o que é um pouco irritante se você deseja fazer algum tratamento de erro personalizado:

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

Esta solução alternativa registrará apenas o nome do erro e o rastreamento da pilha (para que você possa, por exemplo, formatar a mensagem de erro e exibi-la como desejar em outro lugar do código).

O exemplo acima imprimiria apenas o nome do erro seguido pelo rastreamento da pilha, por exemplo:

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)

Ao invés de:

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)
GrayedFox
fonte
1

Caso alguém ainda esteja procurando isso como eu, existe um módulo que podemos usar chamado "rastreamento de pilha". É realmente popular. Link NPM

Então caminhe pelo traço.

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

Ou simplesmente imprima o traço:

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

você pode usar o módulo node-stack-trace , que é um módulo completo para rastrear pilhas de chamadas.

Nitin9791
fonte