Comment imprimer une trace de pile dans Node.js?

Réponses:

615

Tout Errorobjet a un stackmembre qui piège le point où il a été construit.

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

ou plus simplement:

console.trace("Here I am!")
isaacs
la source
1
ou juste sys.puts(new Error().stack)(après avoir ajouté le module système)
sirhc
5
Désormais, sys est déprécié. Il est remplacé par 'util'.
Pindatjuh
12
+1 pour également afficher new Error().stack, ce qui fonctionne dans les cas où vous ne souhaitez pas impliquer la console.
Eugene Beresovsky
1
Un avantage traceest qu'il montre également la ligne / le contexte actuel, ce qui stackn'est pas le cas. L'information est dans l'objet d'erreur si vous voulez créer manuellement cette ligne, je suppose.
studgeek
130
console.log (err.stack) et console.trace () ne vous donnent pas les mêmes résultats. Alors que err.stack vous donne la trace de pile pour l'objet err lui-même (fonctionnant comme nous pensons tous normalement aux exceptions), console.trace () imprime la pile des appels au point où console.trace () est appelée. Donc, si vous détectez une erreur générée par une couche de code plus profonde, console.trace () ne contiendra pas ce code de couche plus profonde dans la trace de la pile car ce code n'est plus sur la pile. Cependant, console.log (err.stack) contiendra les couches plus profondes tant qu'il lancera un objet Error.
d512
200

Maintenant, il y a une fonction dédiée sur la console pour cela:

console.trace()
Mariusz Nowak
la source
11
Assurez - vous de tenir compte du commentaire ci - dessus au sujet console.trace().
Qix - MONICA A ÉTÉ BRUÉE le
5
Par défaut, cela n'affichera que 10 images, vous pouvez utiliser l'argument de ligne de commande pour augmenter cela, par exemple--stack_trace_limit=200
Michael
1
Que faire si vous souhaitez générer un fichier journal?
Ouais.
Cela ne semble pas fonctionner avec des promesses et asynchroniser / attendre, n'est-ce pas?
bluenote10
97

Comme déjà répondu, vous pouvez simplement utiliser la commande trace :

console.trace("I am here");

Cependant, si vous êtes venu à cette question en recherchant comment enregistrer la trace de pile d'une exception , vous pouvez simplement enregistrer l'objet Exception.

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

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

Il enregistrera:

Erreur: quelque chose d'inattendu s'est produit.
    à main (c: \ Users \ Me \ Documents \ MyApp \ app.js: 9: 15)
    à Object. (c: \ Users \ Me \ Documents \ MyApp \ app.js: 17: 1)
    sur Module._compile (module.js: 460: 26)
    sur Object.Module._extensions..js (module.js: 478: 10 )
    à Module.load (module.js: 355: 32)
    à Function.Module._load (module.js: 310: 12)
    à Function.Module.runMain (module.js: 501: 10)
    au démarrage (node.js : 129: 16)
    sur node.js: 814: 3


Si votre version de Node.js est inférieure à 6.0.0 , la journalisation de l'objet Exception ne sera pas suffisante. Dans ce cas, il n'imprimera que:

[Erreur: quelque chose d'inattendu s'est produit.]

Pour la version Node <6, utilisez console.error(e.stack)au lieu de console.error(e)pour imprimer le message d'erreur plus la pile complète, comme le fait la version Node actuelle.


Remarque: si l'exception est créée sous la forme d'une chaîne throw "myException", il n'est pas possible de récupérer la trace de la pile et les e.stackrendements de journalisation non définis .

Pour être en sécurité, vous pouvez utiliser

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

et cela fonctionnera pour les anciennes et les nouvelles versions de Node.js.

Zanon
la source
console.error(e)N'imprimer tout dans l' eobjet, y compris e.stack?
drmrbrewer
1
@drmrbrewer, merci de l'avoir signalé. Il semble que le comportement ait changé entre les versions 4.x et 7.x de Node (probablement un changement V8). J'ai mis à jour ma réponse.
Zanon
1
@drmrbrewer a confirmé que ce comportement a changé sur la version 6.0.0
Zanon
2
désolé, je viens de découvrir quelque chose de crucial. Voir mon commentaire contre le poste connexe: stackoverflow.com/questions/42528677/… . Il semble que la journalisation de l'erreur seule montre en effet tout le contenu de l'erreur, mais en essayant de la concaténer (comme une chaîne) avec un autre texte, seule la partie de message bref sera utilisée. Tout cela a beaucoup plus de sens avec cette réalisation.
drmrbrewer
1
vous sauvez ma journée)
Alex
39

Pour imprimer la trace de pile de la Errorconsole de manière plus lisible:

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

Exemple de résultat:

[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
la source
5

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

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

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

function a() {
    b()
}

a()

console.log(myObj.stack)

La fonction aet bsont capturés dans la pile d'erreurs et stockés dans myObj.

Zheeeng
la source
2
Si vous voulez une erreur d'avoir une stackpropriété, vous aurez besoin d'appeler ce si le nœud> = 6: Error.captureStackTrace(error).
cjbarth
Notez que si vous ne voulez pas que le cadre qui a appelé Error.captureStackTraceapparaisse dans la trace de la pile, vous pouvez l'omettre en le passant comme constructorOptargument.
Ullauri
3

Pour ce que je sais, l'impression de la trace de pile complète dans nodejs n'est pas possible, vous pouvez simplement imprimer une trace de pile "partielle", vous ne pouvez pas voir d'où vous venez dans le code, juste où l'exception se produit. C'est ce que Ryan Dahl explique dans cette vidéo youtube. http://youtu.be/jo_B4LTHi3I au min 56:30 pour être précis. J'espère que cela t'aides

ElHacker
la source
2
vrai, mais le module dans la réponse de @ Timboudreau "corrige" cela
Bogdan D
3

La réponse de @isaacs est correcte, mais si vous avez besoin d'une pile d'erreurs plus spécifique ou plus propre , vous pouvez utiliser cette fonction:

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

   return err.stack;
}

Cette fonction est directement inspirée de la console.tracefonction dans NodeJS .

Code source: version récente ou ancienne version .

Squidward Tentacles
la source
1
cela ne fonctionne pas, affiche uniquement la pile de la ligne actuelle (pas la ligne sur laquelle cette erreur s'est produite). err.stackest une réponse plus correcte.
Ian Zhong
2

Si vous souhaitez uniquement consigner la trace de pile de l'erreur (et non le message d'erreur), le nœud 6 et supérieur inclut automatiquement le nom et le message d'erreur dans la trace de pile, ce qui est un peu gênant si vous souhaitez effectuer une gestion d'erreur personnalisée:

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

Cette solution de contournement enregistrera uniquement le nom de l'erreur et la trace de la pile (afin que vous puissiez, par exemple, formater le message d'erreur et l'afficher comme vous le souhaitez ailleurs dans votre code).

L'exemple ci-dessus afficherait uniquement le nom de l'erreur suivi de la trace de pile, par exemple:

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)

Au lieu 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
la source
1

Au cas où quelqu'un chercherait toujours ceci comme je l'étais, alors il y a un module que nous pouvons utiliser appelé "stack-trace". C'est vraiment populaire. Lien NPM

Parcourez ensuite la trace.

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

Ou imprimez simplement la trace:

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

vous pouvez utiliser le module node-stack-trace qui est un module d'alimentation complet pour suivre les piles d'appels.

Nitin9791
la source