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.

js_
la source
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.

chjj
la source
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
Homme moléculaire
la source
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.

Konstantin Smolyanin
la source
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();
fijiaaron
la source
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
sgouros
la source
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).

jcubic
la source