Comment obtenir le résultat de console.trace () sous forme de chaîne en javascript avec Chrome ou Firefox?


99

console.trace()affiche son résultat sur la console.
Je souhaite obtenir les résultats sous forme de chaîne et les enregistrer dans un fichier.

Je ne définis pas les noms des fonctions et je ne peux pas non plus obtenir leurs noms avec callee.caller.name.


1
cela ne fonctionne pas dans PhantomJS :(
ekkis

Réponses:


103

Je ne suis pas sûr de Firefox, mais dans v8 / chrome, vous pouvez utiliser une méthode appelée sur le constructeur Error captureStackTrace. ( Plus d'infos ici )

Donc, une façon piratée de l'obtenir serait:

var getStackTrace = function() {
  var obj = {};
  Error.captureStackTrace(obj, getStackTrace);
  return obj.stack;
};

console.log(getStackTrace());

Normalement, getStackTraceserait sur la pile quand il est capturé. Le deuxième argument exclut getStackTraced'être inclus dans la trace de pile.


18
Merci pour vos informations. Cela a fonctionné dans Chrome mais pas dans Firefox. Alors j'ai cherché à nouveau et j'ai trouvé Error().stack. Bien que les noms d'objet et de fonction soient perdus dans Firefox et que le nom d'objet soit perdu dans Chrome (le même que Error.captureStackTrace), Error().stackfonctionne les deux navigateurs et me donne suffisamment d'informations pour déboguer.
js_

Exactement le même résultat que la réponse de @Konstantin Smolyanin. Mêmes détails limités en conséquence.
Codebeat le

Cela ne devrait pas être la réponse acceptée. La pile que vous obtenez ici est "coupée" contenant seulement une "partie supérieure", tandis que console.trace () affichera la pile complète. Voir un exemple avec une profondeur de pile 30 ici: stackoverflow.com/questions/62768598/…
mathheadinclouds

34

Error.stack est ce dont vous avez besoin. Cela fonctionne dans Chrome et Firefox. Par exemple

try { var a = {}; a.debug(); } catch(ex) {console.log(ex.stack)}

donnera dans Chrome:

TypeError: Object #<Object> has no method 'debug'
    at eval at <anonymous> (unknown source)
    at eval (native)
    at Object._evaluateOn (unknown source)
    at Object._evaluateAndWrap (unknown source)
    at Object.evaluate (unknown source)

et dans Firefox:

@http://www.google.com.ua/:87 _firebugInjectedEvaluate("with(_FirebugCommandLine){try { var a = {}; a.debug() } catch(ex) {console.log(ex.stack)}\n};")
@http://www.google.com.ua/:87 _firebugEvalEvent([object Event])
@http://www.google.com.ua/:67

2
Merci pour votre réponse. Mais cela ne fonctionne que lorsqu'une exception s'est produite. J'ai besoin d'obtenir la trace de la pile sans exception.
js_

8
Qu'en est-il(new Error).stack
JasonSmith

Cela devrait lancer une exception sur a.debug () - c'est un moyen coûteux d'obtenir la pile, mais cela devrait fonctionner.
fijiaaron

Cette approche est également utile lorsque vous essayez d'obtenir une trace à partir d'un code qui ne peut fonctionner que sur, par exemple PhantomJS ou autre pour une raison quelconque.
waxspin

18

Cela donnera une trace de la pile (sous forme de tableau de chaînes) pour Chrome, Firefox, Opera et IE10 + modernes

function getStackTrace () {

  var stack;

  try {
    throw new Error('');
  }
  catch (error) {
    stack = error.stack || '';
  }

  stack = stack.split('\n').map(function (line) { return line.trim(); });
  return stack.splice(stack[0] == 'Error' ? 2 : 1);
}

Usage:

console.log(getStackTrace().join('\n'));

Il exclut de la pile son propre appel ainsi que le titre "Erreur" qui est utilisé par Chrome et Firefox (mais pas IE).

Il ne devrait pas planter sur les anciens navigateurs, mais simplement renvoyer un tableau vide. Si vous avez besoin d'une solution plus universelle, consultez stacktrace.js . Sa liste de navigateurs pris en charge est vraiment impressionnante, mais à mon avis, elle est très grande pour la petite tâche à laquelle elle est destinée: 37 Ko de texte minifié, y compris toutes les dépendances.


12

Il existe une bibliothèque appelée stacktrace.js qui vous donne des traces de pile entre navigateurs. Vous pouvez l'utiliser simplement en incluant le script et en appelant à tout moment:

var trace = printStackTrace();

Je regarderais github.com/stacktracejs/stacktrace.js car l'implémentation a changé pour prendre en charge les promesses ES6.
Erez Cohen

Notez que pour l'instant cela devrait être utilisé: github.com/stacktracejs/stacktrace.js/tree/stable?files=1 (la nouvelle version n'a pas encore été publiée)
Erez Cohen

10

Ce n'est qu'une amélioration mineure de l'excellent code de Konstantin. Cela réduit un peu les frais de lancer-capture et instancie simplement la pile d'erreur:

function getStackTrace () {
    let stack = new Error().stack || '';
    stack = stack.split('\n').map(function (line) { return line.trim(); });
    return stack.splice(stack[0] == 'Error' ? 2 : 1);
}

Je veux généralement un niveau spécifique de trace de pile (pour mon enregistreur personnalisé), c'est donc également possible lors de l'appel:

getStackTrace()[2]; // get stack trace info 2 levels-deep

6

vous avez seulement besoin var stack = new Error().stack. ceci est une version simplifiée de la réponse @sgouros.

function foo() {
  bar();
}
function bar() {
  baz();
}
function baz() {
  console.log(new Error().stack);
}

foo();

Ne fonctionnera probablement pas dans tous les navigateurs (fonctionne dans Chrome).

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.