Come stampare una traccia dello stack in Node.js?


Risposte:


615

Ogni Erroroggetto ha un stackmembro che intrappola il punto in cui è stato costruito.

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

o più semplicemente:

console.trace("Here I am!")

1
o solo sys.puts(new Error().stack)(dopo aver aggiunto il modulo di sistema)
sirhc

5
A partire da ora, sys è deprecato. È sostituito da 'util'.
Pindatjuh,

12
+1 per mostrare anche new Error().stack, che funziona nei casi in cui non si desidera coinvolgere la console.
Eugene Beresovsky,

1
Uno dei vantaggi traceè che mostra anche la linea / il contesto corrente che stacknon lo fanno. Le informazioni si trovano nell'oggetto errore se si desidera creare manualmente quella riga, suppongo.
Studgeek,

130
console.log (err.stack) e console.trace () non danno gli stessi risultati. Considerando che err.stack fornisce la traccia dello stack per l'oggetto err stesso (funzionando nel modo in cui normalmente pensiamo alle eccezioni), console.trace () stamperà lo stack di chiamate nel punto in cui viene chiamato console.trace (). Pertanto, se si rileva un errore generato da un livello di codice più profondo, console.trace () non conterrà quel codice di livello più profondo nella traccia dello stack poiché tale codice non è più nello stack. Tuttavia, console.log (err.stack) conterrà i layer più profondi fintanto che ha generato un oggetto Error.
d512,

200

Ora c'è una funzione dedicata sulla console per questo:

console.trace()

11
Basta fare in modo di ascoltare il commento di cui sopra circa console.trace().
Qix - MONICA È STATA MISTREATA il

5
Per impostazione predefinita, questo mostrerà solo 10 fotogrammi, è possibile utilizzare l'argomento della riga di comando per aumentarlo, ad esempio--stack_trace_limit=200
Michael,

1
Cosa succede se si desidera eseguire l'output in un file di registro?
Ya.

Non sembra funzionare con le promesse e asincrono / attendono, vero?
bluenote10

97

Come già risposto, puoi semplicemente usare il comando trace :

console.trace("I am here");

Tuttavia, se sei arrivato a questa domanda cercando come registrare la traccia dello stack di un'eccezione , puoi semplicemente registrare l'oggetto Exception.

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

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

Registrerà:

Errore: si è verificato qualcosa di imprevisto.
    a main (c: \ Users \ Me \ Documents \ MyApp \ app.js: 9: 15)
    in Object. (c: \ Users \ Me \ Documents \ MyApp \ app.js: 17: 1)
    su Module._compile (module.js: 460: 26)
    su Object.Module._extensions..js (module.js: 478: 10 )
    su Module.load (module.js: 355: 32)
    su Function.Module._load (module.js: 310: 12)
    su Function.Module.runMain (module.js: 501: 10)
    all'avvio (node.js : 129: 16)
    in node.js: 814: 3


Se la tua versione di Node.js è <di 6.0.0 , la registrazione dell'oggetto Exception non sarà sufficiente. In questo caso, stamperà solo:

[Errore: si è verificato qualcosa di imprevisto.]

Per la versione del nodo <6, utilizzare console.error(e.stack)invece di console.error(e)stampare il messaggio di errore più lo stack completo, come fa l'attuale versione del nodo.


Nota: se l'eccezione viene creata come una stringa throw "myException", non è possibile recuperare la traccia dello stack e i e.stackrendimenti della registrazione non sono definiti .

Per sicurezza, puoi usare

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

e funzionerà con le versioni Node.js vecchie e nuove.


Non console.error(e)stampare tutto in eoggetto, inclusi e.stack?
drmrbrewer,

1
@drmrbrewer, grazie per averlo segnalato. Sembra che il comportamento sia cambiato tra le versioni 4.xe 7.x del nodo (probabilmente una modifica V8). Ho aggiornato la mia risposta.
Zanon

1
@drmrbrewer ha confermato che questo comportamento è cambiato nella versione 6.0.0
Zanon

2
scusate ho appena scoperto qualcosa di cruciale. Vedi il mio commento sul post correlato: stackoverflow.com/questions/42528677/… . Sembra che la registrazione dell'errore da sola mostri effettivamente l'intero contenuto dell'errore, ma il tentativo di concatenarlo (come una stringa) con altro testo provocherà l'utilizzo solo della breve parte del messaggio. Tutto ha molto più senso con quella realizzazione.
drmrbrewer,

1
mi salvi la giornata)
Alex,

39

Per stampare stacktrace di Errorin console in modo più leggibile:

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

Risultato di esempio:

[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

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

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

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

function a() {
    b()
}

a()

console.log(myObj.stack)

La funzione ae bvengono acquisite nello stack degli errori e archiviate in myObj.


2
Se si desidera un errore di avere una stackproprietà, è necessario chiamare questo, se Nodo> = 6: Error.captureStackTrace(error).
cjbarth,

Nota che se non vuoi che il frame che ha chiamato Error.captureStackTracesia mostrato nella traccia dello stack, puoi ometterlo passandolo come constructorOptarg.
Ullauri il

3

Per quello che so non è possibile stampare la traccia dello stack completa in nodejs, puoi semplicemente stampare una traccia dello stack "parziale", non puoi vedere da dove provieni nel codice, proprio dove si verifica l'eccezione. Questo è ciò che Ryan Dahl spiega in questo video di YouTube. http://youtu.be/jo_B4LTHi3I al minimo 56:30 per essere precisi. Spero che sia di aiuto


2
vero, ma il modulo nella risposta di @ Timboudreau "risolve" che
Bogdan D

3

La risposta di @isaacs è corretta, ma se hai bisogno di uno stack di errori più specifico o più pulito , puoi usare questa funzione:

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

   return err.stack;
}

Questa funzione è ispirata direttamente dalla console.tracefunzione in NodeJS .

Codice sorgente: versione recente o versione precedente .


1
non funziona, mostra solo lo stack della riga corrente (non la riga che si è verificato questo errore). err.stackè la risposta più corretta.
Ian Zhong,

2

Se si desidera registrare solo la traccia dello stack dell'errore (e non il messaggio di errore) Il nodo 6 e versioni successive include automaticamente il nome e il messaggio di errore all'interno della traccia dello stack, il che è un po 'fastidioso se si desidera eseguire una gestione personalizzata dell'errore:

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

Questa soluzione alternativa registrerà solo il nome dell'errore e la traccia dello stack (quindi è possibile, ad esempio, formattare il messaggio di errore e visualizzarlo come si desidera altrove nel codice).

L'esempio sopra stamperebbe solo il nome dell'errore seguito dalla traccia dello stack, ad esempio:

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)

Invece di:

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

Nel caso qualcuno lo stia ancora cercando come me, allora c'è un modulo che possiamo usare chiamato "stack-trace". È molto popolare Link NPM

Quindi cammina attraverso la traccia.

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

O semplicemente stampare la traccia:

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.