¿Cómo imprimir un seguimiento de pila en Node.js?

Respuestas:

615

Cualquier Errorobjeto tiene un stackmiembro que atrapa el punto en el que fue construido.

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

o más simplemente:

console.trace("Here I am!")
isaacs
fuente
1
o simplemente sys.puts(new Error().stack)(después de agregar el módulo del sistema)
sirhc el
55
A partir de ahora, sys está depricada. Es reemplazado por 'util'.
Pindatjuh
12
+1 para mostrar también new Error().stack, que funciona en casos en los que no desea involucrar a la consola.
Eugene Beresovsky
1
Una ventaja de tracees que también muestra la línea / contexto actual, que stackno lo hace. Supongo que la información está en el objeto de error si desea crear manualmente esa línea.
studgeek
130
console.log (err.stack) y console.trace () no le dan los mismos resultados. Mientras que err.stack le proporciona el seguimiento de la pila para el objeto err en sí mismo (funcionando de la forma en que normalmente pensamos en las excepciones), console.trace () imprimirá la pila de llamadas en el punto donde se llama a console.trace (). Entonces, si detecta algún error al ser arrojado por una capa de código más profunda, console.trace () no contendrá ese código de capa más profunda en el seguimiento de la pila ya que ese código ya no está en la pila. Sin embargo, console.log (err.stack) contendrá las capas más profundas siempre que arroje un objeto Error.
d512
200

Ahora hay una función dedicada en la consola para eso:

console.trace()
Mariusz Nowak
fuente
11
Sólo asegúrese de prestar atención el comentario anterior acerca console.trace().
Qix - MONICA FUE MALTRATADA el
55
Por defecto, esto solo mostrará 10 fotogramas, puede usar el argumento de la línea de comandos para aumentar esto, por ejemplo--stack_trace_limit=200
Michael
1
¿Qué sucede si desea generar un archivo de registro?
Ya
Eso no parece funcionar con promesas y async / wait, ¿verdad?
bluenote10
97

Como ya se respondió, simplemente puede usar el comando trace :

console.trace("I am here");

Sin embargo, si llegaste a esta pregunta buscando cómo registrar el seguimiento de la pila de una excepción , simplemente puedes registrar el objeto Excepción.

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

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

Se registrará:

Error: ha ocurrido algo inesperado.
    en main (c: \ Users \ Me \ Documents \ MyApp \ app.js: 9: 15)
    en Object. (c: \ Users \ Me \ Documents \ MyApp \ app.js: 17: 1)
    en Module._compile (module.js: 460: 26)
    en Object.Module._extensions..js (module.js: 478: 10 )
    en Module.load (module.js: 355: 32)
    en Function.Module._load (module.js: 310: 12)
    en Function.Module.runMain (module.js: 501: 10)
    al inicio (node.js : 129: 16)
    en node.js: 814: 3


Si su versión de Node.js es <que 6.0.0 , el registro del objeto Exception no será suficiente. En este caso, solo imprimirá:

[Error: ha ocurrido algo inesperado].

Para la versión de nodo <6, use en console.error(e.stack)lugar de console.error(e)imprimir el mensaje de error más la pila completa, como lo hace la versión de nodo actual.


Nota: si la excepción se crea como una cadena como throw "myException", no es posible recuperar el seguimiento de la pila y el e.stackrendimiento del registro no está definido .

Para estar seguro, puedes usar

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

y funcionará para las versiones antiguas y nuevas de Node.js.

Zanon
fuente
¿No console.error(e)imprimirá todo en el eobjeto, incluido e.stack?
drmrbrewer
1
@drmrbrewer, gracias por señalar esto. Parece que el comportamiento ha cambiado entre las versiones de Nodo 4.xy 7.x (probablemente un cambio de V8). He actualizado mi respuesta.
Zanon
1
@drmrbrewer confirmó que este comportamiento cambió en la versión 6.0.0
Zanon
2
lo siento, acabo de descubrir algo crucial. Vea mi comentario sobre la publicación relacionada: stackoverflow.com/questions/42528677/… . Parece que registrar el error por sí solo muestra el contenido completo del error, pero tratar de concatenarlo (como una cadena) con otro texto hará que solo se use la breve parte del mensaje. Todo tiene mucho más sentido con esa realización.
drmrbrewer
1
me salvas el día)
Alex
39

Para imprimir stacktrace Erroren la consola de una manera más legible:

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

Resultado de ejemplo:

[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
fuente
5

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

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

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

function a() {
    b()
}

a()

console.log(myObj.stack)

La función ay bse capturan en la pila de errores y se almacenan en myObj.

Zheeeng
fuente
2
Si desea que un error de tener una stackpropiedad, tendrá que llamar a esto si el Nodo> = 6: Error.captureStackTrace(error).
cjbarth
Tenga en cuenta que si no desea que el marco que llamó se Error.captureStackTracemuestre en el seguimiento de la pila, puede omitirlo pasándolo como el constructorOptargumento.
Ullauri
3

Por lo que sé, imprimir la traza completa de la pila en nodejs no es posible, solo puede imprimir una traza de pila "parcial", no puede ver de dónde vino en el código, solo dónde ocurre la excepción. Eso es lo que Ryan Dahl explica en este video de YouTube. http://youtu.be/jo_B4LTHi3I a las 56:30 min para ser precisos. Espero que esto ayude

ElHacker
fuente
2
cierto, pero el módulo en la respuesta de @ Timboudreau "arregla" eso
Bogdan D
3

La respuesta de @isaacs es correcta, pero si necesita una pila de errores más específica o más limpia , puede usar esta función:

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

   return err.stack;
}

Esta función está inspirada directamente de la console.tracefunción en NodeJS .

Código fuente: versión reciente o versión antigua .

Calamardo Tentáculos
fuente
1
no funciona, solo muestra la pila de la línea actual (no la línea en la que se produjo este error). err.stackEs la respuesta más correcta.
Ian Zhong
2

Si solo desea registrar el seguimiento de la pila del error (y no el mensaje de error), el Nodo 6 y superior incluye automáticamente el nombre del error y el mensaje dentro del seguimiento de la pila, lo cual es un poco molesto si desea realizar un tratamiento de errores personalizado:

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

Esta solución solo registrará el nombre del error y el seguimiento de la pila (para que pueda, por ejemplo, formatear el mensaje de error y mostrarlo como desee en otro lugar de su código).

El ejemplo anterior solo imprimirá el nombre del error seguido del seguimiento de la pila, por ejemplo:

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)

En vez 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
fuente
1

En caso de que alguien todavía esté buscando esto como yo, entonces hay un módulo que podemos usar llamado "stack-trace". Es muy popular Enlace NPM

Luego camina a través del rastro.

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

O simplemente imprima la traza:

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

puede usar el módulo node-stack-trace , que es un módulo lleno de energía para rastrear las pilas de llamadas.

Nitin9791
fuente