Wie bekomme ich das Ergebnis von console.trace () als String in Javascript mit Chrome oder Firefox?

98

console.trace()gibt das Ergebnis auf der Konsole aus.
Ich möchte die Ergebnisse als Zeichenfolge abrufen und in einer Datei speichern.

Ich definiere keine Namen für Funktionen und kann auch ihre Namen nicht mit bekommen callee.caller.name.

js_
quelle
1
Dies funktioniert nicht in PhantomJS :(
Ekkis

Antworten:

103

Ich bin mir bei Firefox nicht sicher, aber in Version 8 / Chrome können Sie eine Methode für den aufgerufenen Fehlerkonstruktor verwenden captureStackTrace. ( Mehr Infos hier )

Ein hackiger Weg, um es zu bekommen, wäre also:

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

console.log(getStackTrace());

Normalerweise befindet getStackTracees sich auf dem Stapel, wenn es erfasst wird. Das zweite Argument schließt getStackTraceaus, dass es nicht in die Stapelverfolgung aufgenommen wird.

chjj
quelle
18
Danke für Ihre Information. Das hat in Chrom funktioniert, aber nicht in Firefox. Also habe ich nochmal gesucht und gefunden Error().stack. Obwohl Objekt- und Funktionsnamen in Firefox verloren gehen und Objektnamen in Chrome (wie in Error.captureStackTrace) verloren gehen, Error().stackfunktionieren beide Browser und es gibt mir genügend Informationen zum Debuggen.
js_
Genau das gleiche Ergebnis wie die Antwort von @Konstantin Smolyanin. Gleiche begrenzte Details als Ergebnis.
Codebeat
Dies sollte nicht die akzeptierte Antwort sein. Der Stapel, den Sie hier erhalten, ist "abgeschnitten" und enthält nur einen "oberen Teil", während console.trace () den gesamten Stapel anzeigt. Ein Beispiel mit der Stapeltiefe
mathheadinclouds
34

Error.stack ist das, was Sie brauchen. Es funktioniert in Chrome und Firefox. Beispielsweise

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

wird in Chrome geben:

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)

und in 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
Molecular Man
quelle
2
Danke für deine Antwort. Dies funktioniert jedoch nur, wenn eine Ausnahme aufgetreten ist. Ich muss ausnahmslos Stack-Trace erhalten.
js_
8
Was ist mit(new Error).stack
JasonSmith
Dies sollte eine Ausnahme bei a.debug () auslösen - es ist ein teurer Weg, um den Stack zu erhalten, sollte aber funktionieren.
Fijiaaron
Dieser Ansatz ist auch nützlich, wenn Sie versuchen, eine Ablaufverfolgung von einem Code abzurufen, der nur ausgeführt werden kann, z. B. PhantomJS oder dergleichen, aus welchem ​​Grund auch immer.
Waxspin
18

Dies gibt eine Stapelverfolgung (als Array von Zeichenfolgen) für modernes Chrome, Firefox, Opera und IE10 +

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);
}

Verwendung:

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

Es schließt den eigenen Aufruf sowie den Titel "Fehler", der von Chrome und Firefox (aber nicht vom IE) verwendet wird, vom Stapel aus.

Es sollte nicht in älteren Browsern abstürzen, sondern nur ein leeres Array zurückgeben. Wenn Sie eine universellere Lösung benötigen, schauen Sie sich stacktrace.js an . Die Liste der unterstützten Browser ist wirklich beeindruckend, aber meiner Meinung nach ist sie für die kleine Aufgabe, für die sie bestimmt ist, sehr groß: 37 KB minimierter Text einschließlich aller Abhängigkeiten.

Konstantin Smolyanin
quelle
12

Es gibt eine Bibliothek namens stacktrace.js , mit der Sie browserübergreifende Stack-Traces erhalten. Sie können es einfach verwenden, indem Sie das Skript einfügen und an einem beliebigen Punkt aufrufen:

var trace = printStackTrace();
Fidschiaaron
quelle
Ich würde auf github.com/stacktracejs/stacktrace.js schauen, da sich die Implementierung geändert hat, um ES6-Versprechen zu unterstützen.
Erez Cohen
Beachten Sie, dass dies vorerst verwendet werden sollte: github.com/stacktracejs/stacktrace.js/tree/stable?files=1 (neue Version wurde noch nicht veröffentlicht)
Erez Cohen
9

Dies ist nur eine geringfügige Verbesserung von Konstantins ausgezeichnetem Code. Es reduziert die Kosten für das Werfen ein wenig und instanziiert nur den Fehlerstapel:

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);
}

Normalerweise möchte ich eine bestimmte Ebene der Stapelverfolgung (für meinen benutzerdefinierten Logger), daher ist dies auch möglich, wenn Folgendes aufgerufen wird:

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

du brauchst nur var stack = new Error().stack. Dies ist eine vereinfachte Version von @sgouros Antwort.

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

foo();

Funktioniert wahrscheinlich nicht in jedem Browser (funktioniert in Chrome).

jcubic
quelle