Wie kann ich einen JavaScript-Stack-Trace abrufen, wenn ich eine Ausnahme auslöse?

519

throw "AArrggg"Wie kann ich den Stack-Trace abrufen (in Firebug oder auf andere Weise), wenn ich selbst eine JavaScript-Ausnahme auslöse (z. B. )? Im Moment bekomme ich nur die Nachricht.

Bearbeiten : Wie viele unten stehende Personen gepostet haben, ist es möglich, einen Stack-Trace für eine JavaScript-Ausnahme abzurufen, aber ich möchte einen Stack-Trace für meine Ausnahmen abrufen. Zum Beispiel:

function foo() {
    bar(2);
}
function bar(n) {
    if (n < 2)
        throw "Oh no! 'n' is too small!"
    bar(n-1);
}

Wenn fooaufgerufen wird, möchte ich ein Stack - Trace erhalten , die , um die Anrufe umfasst foo, bar, bar.

David Wolever
quelle
1
mögliches Duplikat von Javascript Exception Stack Trace
Ripper234
Der Bug ist im Firebug Bug Tracker seit 2008 noch offen: code.google.com/p/fbug/issues/detail?id=1260 - star it!
Miller Medeiros
13
Die Antwort sollte "neuen Fehler werfen ('arrrgh');" siehe diese schön geschriebene Seite: devthought.com/2011/12/22/a-string-is-not-an-error
elegante Würfel
1
(2013) Sie können jetzt in Firebug unter Firefox Stapelspuren abrufen, auch wenn dies einfach ist throw 'arrrgh';, und sie scheinen dieselben zu sein wie bei throw new Error('arrrgh');. Der Chrome-Debugger muss jedoch throw new Error('arrrgh');wie angegeben noch verwendet werden (Chrome scheint jedoch viel detailliertere Spuren zu liefern).
user56reinstatemonica8
26
@ChetanSastry Ich habe nach 'Javascript Stack Trace' gegoogelt und dies war das erste Ergebnis
David Sykes

Antworten:

756

Edit 2 (2017):

In allen modernen Browsern können Sie einfach anrufen: console.trace(); (MDN-Referenz)

Edit 1 (2013):

Eine bessere (und einfachere) Lösung, wie in den Kommentaren zur ursprünglichen Frage ausgeführt, besteht darin, die stackEigenschaft eines ErrorObjekts wie folgt zu verwenden :

function stackTrace() {
    var err = new Error();
    return err.stack;
}

Dies erzeugt eine Ausgabe wie folgt:

DBX.Utils.stackTrace@http://localhost:49573/assets/js/scripts.js:44
DBX.Console.Debug@http://localhost:49573/assets/js/scripts.js:9
.success@http://localhost:49573/:462
x.Callbacks/c@http://localhost:49573/assets/js/jquery-1.10.2.min.js:4
x.Callbacks/p.fireWith@http://localhost:49573/assets/js/jquery-1.10.2.min.js:4
k@http://localhost:49573/assets/js/jquery-1.10.2.min.js:6
.send/r@http://localhost:49573/assets/js/jquery-1.10.2.min.js:6

Geben Sie den Namen der aufrufenden Funktion zusammen mit der URL, ihrer aufrufenden Funktion usw. an.

Original (2009):

Eine modifizierte Version dieses Snippets kann etwas helfen:

function stacktrace() { 
  function st2(f) {
    return !f ? [] : 
        st2(f.caller).concat([f.toString().split('(')[0].substring(9) + '(' + f.arguments.join(',') + ')']);
  }
  return st2(arguments.callee.caller);
}
Eugene Morozov
quelle
11
Ich bin mir nicht sicher, warum dies nicht mehr gewählt wird - die anderen Antworten haben bei mir nicht so gut funktioniert. Übrigens, stellen Sie sicher, dass Sie Argumente nicht als Array behandeln (aktualisiertes Snippet hier: gist.github.com/965603 )
ripper234
1
funktioniert nicht in Chrome, Tacktrace (): [Ausnahme: TypeError: Objekt # <Objekt> hat keine Methode
Hetaoblog
3
Siehe Kommentar zur ursprünglichen Frage: Sie benötigen keinen benutzerdefinierten Code, verwenden Sie einfach "throw new Error ('arrrgh')"
Joshua Richardson
16
Error.stack ist im IE undefiniert, funktioniert nur in Chrome und Mozilla Firefox
Philipp Munin
4
Beachten Sie, dass dies callerjetzt veraltet ist und calleeaus dem strengen ES5-Modus entfernt wird. Hier ist, warum stackoverflow.com/questions/103598/…
PhilT
187

Beachten Sie, dass Chrom / Chrom (andere Browser, die V8 verwenden) und auch Firefox über eine praktische Oberfläche verfügen, über die eine Stacktrace über eine Stack- Eigenschaft für Fehlerobjekte abgerufen werden kann.

try {
   // Code throwing an exception
} catch(e) {
  console.log(e.stack);
}

Dies gilt sowohl für die Basisausnahmen als auch für die, die Sie selbst werfen. (Es wird davon ausgegangen, dass Sie die Fehlerklasse verwenden, was ohnehin eine gute Vorgehensweise ist.)

Weitere Informationen finden Sie in der V8-Dokumentation

Jocelyn delalande
quelle
12
Firefox unterstützt die .stackEigenschaft auch.
Kennytm
2
Ich wünschte, ich könnte 100 Mal upvoten! Vielen Dank, Jocelyn. Es hat wirklich sehr geholfen
safrazik
1
Sie können auch verwenden, console.error(e.stack);so dass es wie eine Standardausnahmemeldung aussieht
Bruno Peres
80

In Firefox müssen Sie die Ausnahme anscheinend nicht auslösen. Es ist ausreichend zu tun

e = new Error();
console.log(e.stack);
Justin L.
quelle
Funktioniert auch in mobilen Apps (mit JQM erstellt).
Samik R
Funktioniert auch in Chrom (Version 43 sowieso).
Andy Beverley
In Firefox 59 funktioniert dies nicht, wenn es über aufgerufen window.onerrorwird. Es zeigt einen fast leeren Stapel mit nur der onerrorFunktion.
Code4R7
Noch besser, Sie könnten tun: console.log(new Error().stack)> :(> :(> :(
Andrew
25

Wenn Sie einen Firebug haben, wird die Option für alle Fehler auf der Registerkarte "Skript" unterbrochen. Sobald das Skript Ihren Haltepunkt erreicht hat, können Sie das Stapelfenster von firebug anzeigen:

Bildschirmfoto

Helephant
quelle
5
Hrm, das scheint nicht zu funktionieren. Es stoppt mich in einem Debugger über Fehler, die durch Javascript ausgelöst wurden (z. B. undefinierte Variablenfehler), aber wenn ich meine eigenen Ausnahmen auslöse, erhalte ich immer noch nichts anderes als die Meldung "Nicht erfasste Ausnahme".
David Wolever
11

Eine gute (und einfache) Lösung, wie in den Kommentaren zur ursprünglichen Frage ausgeführt, besteht darin, die stackEigenschaft eines ErrorObjekts wie folgt zu verwenden :

function stackTrace() {
    var err = new Error();
    return err.stack;
}

Dies erzeugt eine Ausgabe wie folgt:

DBX.Utils.stackTrace@http://localhost:49573/assets/js/scripts.js:44
DBX.Console.Debug@http://localhost:49573/assets/js/scripts.js:9
.success@http://localhost:49573/:462
x.Callbacks/c@http://localhost:49573/assets/js/jquery-1.10.2.min.js:4
x.Callbacks/p.fireWith@http://localhost:49573/assets/js/jquery-1.10.2.min.js:4
k@http://localhost:49573/assets/js/jquery-1.10.2.min.js:6
.send/r@http://localhost:49573/assets/js/jquery-1.10.2.min.js:6

Geben Sie den Namen der aufrufenden Funktion zusammen mit der URL und der Zeilennummer, ihrer aufrufenden Funktion usw. an.

Ich habe eine wirklich ausgefeilte und hübsche Lösung, die ich für ein Projekt entwickelt habe, an dem ich gerade arbeite, und ich habe sie extrahiert und ein wenig überarbeitet, um sie zu verallgemeinern. Hier ist es:

(function(context){
    // Only global namespace.
    var Console = {
        //Settings
        settings: {
            debug: {
                alwaysShowURL: false,
                enabled: true,
                showInfo: true
            },
            stackTrace: {
                enabled: true,
                collapsed: true,
                ignoreDebugFuncs: true,
                spacing: false
            }
        }
    };

    // String formatting prototype function.
    if (!String.prototype.format) {
        String.prototype.format = function () {
            var s = this.toString(),
                args = typeof arguments[0],
                args = (("string" == args || "number" == args) ? arguments : arguments[0]);
            if (!arguments.length)
                return s;
            for (arg in args)
                s = s.replace(RegExp("\\{" + arg + "\\}", "gi"), args[arg]);
            return s;
        }
    }

    // String repeating prototype function.
    if (!String.prototype.times) {
        String.prototype.times = function () {
            var s = this.toString(),
                tempStr = "",
                times = arguments[0];
            if (!arguments.length)
                return s;
            for (var i = 0; i < times; i++)
                tempStr += s;
            return tempStr;
        }
    }

    // Commonly used functions
    Console.debug = function () {
        if (Console.settings.debug.enabled) {
            var args = ((typeof arguments !== 'undefined') ? Array.prototype.slice.call(arguments, 0) : []),
                sUA = navigator.userAgent,
                currentBrowser = {
                    firefox: /firefox/gi.test(sUA),
                    webkit: /webkit/gi.test(sUA),
                },
                aLines = Console.stackTrace().split("\n"),
                aCurrentLine,
                iCurrIndex = ((currentBrowser.webkit) ? 3 : 2),
                sCssBlack = "color:black;",
                sCssFormat = "color:{0}; font-weight:bold;",
                sLines = "";

            if (currentBrowser.firefox)
                aCurrentLine = aLines[iCurrIndex].replace(/(.*):/, "$1@").split("@");
            else if (currentBrowser.webkit)
                aCurrentLine = aLines[iCurrIndex].replace("at ", "").replace(")", "").replace(/( \()/gi, "@").replace(/(.*):(\d*):(\d*)/, "$1@$2@$3").split("@");

            // Show info if the setting is true and there's no extra trace (would be kind of pointless).
            if (Console.settings.debug.showInfo && !Console.settings.stackTrace.enabled) {
                var sFunc = aCurrentLine[0].trim(),
                    sURL = aCurrentLine[1].trim(),
                    sURL = ((!Console.settings.debug.alwaysShowURL && context.location.href == sURL) ? "this page" : sURL),
                    sLine = aCurrentLine[2].trim(),
                    sCol;

                if (currentBrowser.webkit)
                    sCol = aCurrentLine[3].trim();

                console.info("%cOn line %c{0}%c{1}%c{2}%c of %c{3}%c inside the %c{4}%c function:".format(sLine, ((currentBrowser.webkit) ? ", column " : ""), ((currentBrowser.webkit) ? sCol : ""), sURL, sFunc),
                             sCssBlack, sCssFormat.format("red"),
                             sCssBlack, sCssFormat.format("purple"),
                             sCssBlack, sCssFormat.format("green"),
                             sCssBlack, sCssFormat.format("blue"),
                             sCssBlack);
            }

            // If the setting permits, get rid of the two obvious debug functions (Console.debug and Console.stackTrace).
            if (Console.settings.stackTrace.ignoreDebugFuncs) {
                // In WebKit (Chrome at least), there's an extra line at the top that says "Error" so adjust for this.
                if (currentBrowser.webkit)
                    aLines.shift();
                aLines.shift();
                aLines.shift();
            }

            sLines = aLines.join(((Console.settings.stackTrace.spacing) ? "\n\n" : "\n")).trim();

            trace = typeof trace !== 'undefined' ? trace : true;
            if (typeof console !== "undefined") {
                for (var arg in args)
                    console.debug(args[arg]);

                if (Console.settings.stackTrace.enabled) {
                    var sCss = "color:red; font-weight: bold;",
                        sTitle = "%c Stack Trace" + " ".times(70);

                    if (Console.settings.stackTrace.collapsed)
                        console.groupCollapsed(sTitle, sCss);
                    else
                        console.group(sTitle, sCss);

                    console.debug("%c" + sLines, "color: #666666; font-style: italic;");

                    console.groupEnd();
                }
            }
        }
    }
    Console.stackTrace = function () {
        var err = new Error();
        return err.stack;
    }

    context.Console = Console;
})(window);

Schau es dir auf GitHub an (derzeit v1.2)! Sie können es wie Console.debug("Whatever");folgt verwenden und es wird abhängig von den Einstellungen in Consoledie Ausgabe und einen Stack-Trace drucken (oder einfach nur Infos / gar nichts extra). Hier ist ein Beispiel:

Console.js

Stellen Sie sicher, dass Sie mit den Einstellungen im ConsoleObjekt herumspielen! Sie können einen Abstand zwischen den Linien der Ablaufverfolgung hinzufügen und diese vollständig deaktivieren. Hier ist es mit Console.tracegesetzt auf false:

Keine Spur

Sie können sogar das erste Bit info gezeigt (Satz deaktivieren Console.settings.debug.showInfozu false) oder deaktivieren Sie das Debuggen vollständig (Satz Console.settings.debug.enabledauf false) , so dass Sie nie wieder eine Debug - Anweisung kommentieren Sie müssen! Lass sie einfach drin und das bringt nichts.

Gabriel Nahmias
quelle
10

Ich glaube nicht, dass irgendetwas eingebaut ist, das Sie verwenden können, aber ich habe viele Beispiele von Leuten gefunden, die ihre eigenen rollen.

Mark Biek
quelle
Ah, danke - der erste Link dort scheint zu funktionieren (obwohl der Mangel an Rekursionsunterstützung ihn möglicherweise nicht funktionsfähig macht).
David Wolever
Ja, ich habe auf den ersten Blick keine gesehen, die eine Rekursion unterstützt. Ich bin gespannt, ob es dafür eine gute Lösung gibt.
Mark Biek
1
Ich denke, der zweite Link sollte die Rekursion für Firefox und Opera unterstützen, da er den Fehlerstapel-Trace verwendet, anstatt einen manuell mit der Argumentvariablen zu erstellen. Ich würde gerne hören, ob Sie eine browserübergreifende Lösung für das Rekursionsproblem finden (der erste Artikel gehört mir). :)
Helephant
Helephant: Der zweite funktioniert hier nicht, weil es, wenn ich die Ausnahme abfange, ein "String" ist (dh kein "e.stack"): foo = function () {throw "Arg"; } try {foo (); } catch (e) {/ * typeof e == "string" * /} Vielleicht werfe ich es falsch? (Beginnen Sie obligatorisch darüber zu schimpfen, wie dumm Javascript-Tutorials sind ...)
David Wolever
Versuchen Sie, ein Objekt zu werfen : throw { name: 'NameOfException', message: 'He's dead, Jim' }.
Aaron Digulla
7

Sie können auf die stack( stacktracein Opera) Eigenschaften einer ErrorInstanz zugreifen, auch wenn Sie sie geworfen haben. Die Sache ist, Sie müssen sicherstellen, dass Sie verwenden throw new Error(string)(vergessen Sie nicht das neue stattthrow string .

Beispiel:

try {
    0++;
} catch (e) {
    var myStackTrace = e.stack || e.stacktrace || "";
}
Eli Gray
quelle
Stacktrace funktioniert in Opera nicht. Ich kann nicht einmal etwas darüber finden.
NVI
@NV: Es scheint, dass Stacktrace nicht auf vom Benutzer erstellten Fehlern basiert. Sie sollten dies stattdessen tun: Versuchen Sie {0 ++} catch (e) {myStackTrace = e.stack || e.stacktrace}
Eli Gray
7

Dies gibt eine Stapelverfolgung (als Array von Zeichenfolgen) für modernes Chrome, Opera, Firefox 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);
}

Verwendungszweck:

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 sehr groß für die kleine Aufgabe, für die sie bestimmt ist: 37 KB minimierter Text einschließlich aller Abhängigkeiten.

Konstantin Smolyanin
quelle
7

Ein Update zu Eugenes Antwort: Das Fehlerobjekt muss ausgelöst werden, damit der IE (bestimmte Versionen?) Die stackEigenschaft füllen kann. Das Folgende sollte besser funktionieren als sein aktuelles Beispiel und eine Rückkehr undefinedim IE vermeiden .

function stackTrace() {
  try {
    var err = new Error();
    throw err;
  } catch (err) {
    return err.stack;
  }
}

Hinweis 1: Diese Art von Dingen sollte nur beim Debuggen ausgeführt und im Live-Modus deaktiviert werden, insbesondere wenn sie häufig aufgerufen werden. Hinweis 2: Dies funktioniert möglicherweise nicht in allen Browsern, scheint jedoch in FF und IE 11 zu funktionieren, was meinen Anforderungen entspricht.

Patrick Seymour
quelle
6

Eine Möglichkeit, einen echten Stack-Trace für Firebug zu erhalten, besteht darin, einen echten Fehler wie das Aufrufen einer undefinierten Funktion zu erstellen:

function foo(b){
  if (typeof b !== 'string'){
    // undefined Error type to get the call stack
    throw new ChuckNorrisError("Chuck Norris catches you.");
  }
}

function bar(a){
  foo(a);
}

foo(123);

Oder verwenden Sie console.error()gefolgt von einer throwAnweisung, da console.error()die Stapelverfolgung angezeigt wird.

Miller Medeiros
quelle
4

Dieser Polyfill-Code funktioniert in modernen (2017) Browsern (IE11, Opera, Chrome, FireFox, Yandex):

printStackTrace: function () {
    var err = new Error();
    var stack = err.stack || /*old opera*/ err.stacktrace || ( /*IE11*/ console.trace ? console.trace() : "no stack info");
    return stack;
}

Andere Antwort:

function stackTrace() {
  var err = new Error();
  return err.stack;
}

funktioniert nicht in IE 11!

Mit arguments.callee.caller - arbeitet nicht im Strict - Modus in jedem Browser!

Petr Varyagin
quelle
3

In Google Chrome (Version 19.0 und höher) funktioniert das Auslösen einer Ausnahme einwandfrei. Zum Beispiel:

/* file: code.js, line numbers shown */

188: function fa() {
189:    console.log('executing fa...');
190:    fb();
191: }
192:
193: function fb() {
194:    console.log('executing fb...');
195:    fc()
196: }
197:
198: function fc() {
199:    console.log('executing fc...');
200:    throw 'error in fc...'
201: }
202:
203: fa();

zeigt den Stack-Trace an der Konsolenausgabe des Browsers an:

executing fa...                         code.js:189
executing fb...                         code.js:194
executing fc...                         cdoe.js:199
/* this is your stack trace */
Uncaught error in fc...                 code.js:200
    fc                                  code.js:200
    fb                                  code.js:195
    fa                                  code.js:190
    (anonymous function)                code.js:203

Ich hoffe das hilft.

Rabih Kodeih
quelle
3

Funktion:

function print_call_stack(err) {
    var stack = err.stack;
    console.error(stack);
}

Anwendungsfall:

     try{
         aaa.bbb;//error throw here
     }
     catch (err){
         print_call_stack(err); 
     }
Jaskey
quelle
2
<script type="text/javascript"
src="https://rawgithub.com/stacktracejs/stacktrace.js/master/stacktrace.js"></script>
<script type="text/javascript">
    try {
        // error producing code
    } catch(e) {
        var trace = printStackTrace({e: e});
        alert('Error!\n' + 'Message: ' + e.message + '\nStack trace:\n' + trace.join('\n'));
        // do something else with error
    }
</script>

Dieses Skript zeigt den Fehler an

Amir Buzo
quelle
2
function stacktrace(){
  return (new Error()).stack.split('\n').reverse().slice(0,-2).reverse().join('\n');
}
Denis Orlov
quelle
2
Während dieser Code die Frage möglicherweise beantwortet, würde die Bereitstellung eines zusätzlichen Kontexts darüber, wie und / oder warum das Problem gelöst wird, den langfristigen Wert der Antwort verbessern.
Donald Duck
1

Etwas spät zur Party, aber hier ist eine andere Lösung, die automatisch erkennt ob argument.callee verfügbar ist, und wenn nicht, den neuen Error (). Stack verwendet. Getestet in Chrom, Safari und Firefox.

2 Varianten - stackFN (n) gibt Ihnen den Namen der Funktion n vom unmittelbaren Aufrufer entfernt und stackArray () gibt Ihnen ein Array, wobei stackArray () [0] der unmittelbare Aufrufer ist.

Probieren Sie es unter http://jsfiddle.net/qcP9y/6/ aus.

// returns the name of the function at caller-N
// stackFN()  = the immediate caller to stackFN
// stackFN(0) = the immediate caller to stackFN
// stackFN(1) = the caller to stackFN's caller
// stackFN(2) = and so on
// eg console.log(stackFN(),JSON.stringify(arguments),"called by",stackFN(1),"returns",retval);
function stackFN(n) {
    var r = n ? n : 0, f = arguments.callee,avail=typeof f === "function",
        s2,s = avail ? false : new Error().stack;
    if (s) {
        var tl=function(x) { s = s.substr(s.indexOf(x) + x.length);},
        tr = function (x) {s = s.substr(0, s.indexOf(x) - x.length);};
        while (r-- >= 0) {
            tl(")");
        }
        tl(" at ");
        tr("(");
        return s;
    } else {
        if (!avail) return null;
        s = "f = arguments.callee"
        while (r>=0) {
            s+=".caller";
            r--;   
        }
        eval(s);
        return f.toString().split("(")[0].trim().split(" ")[1];
    }
}
// same as stackFN() but returns an array so you can work iterate or whatever.
function stackArray() {
    var res=[],f = arguments.callee,avail=typeof f === "function",
        s2,s = avail ? false : new Error().stack;
    if (s) {
        var tl=function(x) { s = s.substr(s.indexOf(x) + x.length);},
        tr = function (x) {s = s.substr(0, s.indexOf(x) - x.length);};
        while (s.indexOf(")")>=0) {
            tl(")");
            s2= ""+s;
            tl(" at ");
            tr("(");
            res.push(s);
            s=""+s2;
        }
    } else {
        if (!avail) return null;
        s = "f = arguments.callee.caller"
        eval(s);
        while (f) {
            res.push(f.toString().split("(")[0].trim().split(" ")[1]);
            s+=".caller";
            eval(s);
        }
    }
    return res;
}


function apple_makes_stuff() {
    var retval = "iPhones";
    var stk = stackArray();

    console.log("function ",stk[0]+"() was called by",stk[1]+"()");
    console.log(stk);
    console.log(stackFN(),JSON.stringify(arguments),"called by",stackFN(1),"returns",retval);
    return retval;
}



function apple_makes (){
    return apple_makes_stuff("really nice stuff");
}

function apple () {
    return apple_makes();
}

   apple();
nicht synchronisiert
quelle
1

Sie können diese Bibliothek verwenden http://www.stacktracejs.com/ . Es ist sehr gut

Aus der Dokumentation

Sie können auch Ihren eigenen Fehler übergeben, um einen Stacktrace zu erhalten, der in IE oder Safari 5 nicht verfügbar ist.

<script type="text/javascript" src="https://rawgithub.com/stacktracejs/stacktrace.js/master/stacktrace.js"></script>
<script type="text/javascript">
    try {
        // error producing code
    } catch(e) {
        var trace = printStackTrace({e: e});
        alert('Error!\n' + 'Message: ' + e.message + '\nStack trace:\n' + trace.join('\n'));
        // do something else with error
    }
</script>
Doua Beri
quelle
Die verlinkte Quelle https://rawgithub.com/stacktracejs/stacktrace.js/master/stacktrace.jsist eine alte Version, die neueste stabile Version (passend zum Code-Snippet) ist hier:https://raw.githubusercontent.com/stacktracejs/stacktrace.js/stable/stacktrace.js
Frederic Leitenberger
1

Hier ist eine Antwort, die Ihnen maximale Leistung (IE 6+) und maximale Kompatibilität bietet. Kompatibel mit IE 6!

    function stacktrace( log_result ) {
    	var trace_result;
    // IE 6 through 9 compatibility
    // this is NOT an all-around solution because
    // the callee property of arguments is depredicated
    /*@cc_on
    	// theese fancy conditinals make this code only run in IE
    	trace_result = (function st2(fTmp) {
    		// credit to Eugene for this part of the code
    		return !fTmp ? [] :
    			st2(fTmp.caller).concat([fTmp.toString().split('(')[0].substring(9) + '(' + fTmp.arguments.join(',') + ')']);
    	})(arguments.callee.caller);
    	if (log_result) // the ancient way to log to the console
    		Debug.write( trace_result );
    	return trace_result;
    @*/
    	console = console || Console;	// just in case
    	if (!(console && console.trace) || !log_result){
    		// for better performance in IE 10
    		var STerror=new Error();
    		var unformated=(STerror.stack || STerror.stacktrace);
    		trace_result = "\u25BC console.trace" + unformated.substring(unformated.indexOf('\n',unformated.indexOf('\n'))); 
    	} else {
    		// IE 11+ and everyone else compatibility
    		trace_result = console.trace();
    	}
    	if (log_result)
    		console.log( trace_result );
    	
    	return trace_result;
    }
// test code
(function testfunc(){
	document.write( "<pre>" + stacktrace( false ) + "</pre>" );
})();

Jack Giffin
quelle
0

Es ist einfacher, in Firefox einen Stack-Trace zu erhalten als in IE. Grundsätzlich möchten Sie jedoch Folgendes tun:

Wickeln Sie den "problematischen" Code in einen Try / Catch-Block ein:

try {
    // some code that doesn't work
    var t = null;
    var n = t.not_a_value;
}
    catch(e) {
}

Wenn Sie den Inhalt des "Fehler" -Objekts untersuchen, enthält es die folgenden Felder:

e.fileName: Die Quelldatei / Seite, von der das Problem stammt. e.lineNumber: Die Zeilennummer in der Datei / Seite, auf der das Problem aufgetreten ist. e.message: Eine einfache Nachricht, die beschreibt, welche Art von Fehler aufgetreten ist. e.name: Der Typ Der Fehler, der aufgetreten ist, sollte im obigen Beispiel 'TypeError' sein. e.stack: Enthält den Stack-Trace, der die Ausnahme verursacht hat

Ich hoffe das hilft dir weiter.

Michael
quelle
1
Falsch. Er versucht, seine eigenen Ausnahmen zu fangen. Wenn er "asdfg" auslöst, erhält er ein String-Objekt, kein Ausnahmeobjekt. Er versucht nicht, eingebaute Ausnahmen zu fangen.
Ivan Vučica
0

Ich musste eine endlose Rekursion in smartgwt mit IE11 untersuchen. Um tiefer zu untersuchen, brauchte ich eine Stapelverfolgung. Das Problem war, dass ich die Entwicklungskonsole nicht verwenden konnte, da die Reproduktion auf diese Weise schwieriger war.
Verwenden Sie in einer Javascript-Methode Folgendes:

try{ null.toString(); } catch(e) { alert(e.stack); }
kirilv
quelle
alert ((neuer Fehler ()). stack);
reiches remer
0

Wow - ich sehe seit 6 Jahren keine einzige Person, die vorschlägt, dass wir zuerst prüfen, ob stack verfügbar ist, bevor sie verwenden! Das Schlimmste, was Sie in einem Fehlerbehandler tun können, ist, einen Fehler auszulösen, weil Sie etwas aufrufen, das nicht vorhanden ist.

Wie andere bereits gesagt haben, stackwird die Verwendung in IE9 oder früheren Versionen nicht unterstützt , obwohl sie derzeit größtenteils sicher ist.

Ich protokolliere meine unerwarteten Fehler und eine Stapelverfolgung ist ziemlich wichtig. Für maximale Unterstützung überprüfe ich zuerst, obError.prototype.stack es eine Funktion gibt. Wenn ja, dann ist es sicher zu verwenden error.stack.

        window.onerror = function (message: string, filename?: string, line?: number, 
                                   col?: number, error?: Error)
        {
            // always wrap error handling in a try catch
            try 
            {
                // get the stack trace, and if not supported make our own the best we can
                var msg = (typeof Error.prototype.stack == 'function') ? error.stack : 
                          "NO-STACK " + filename + ' ' + line + ':' + col + ' + message;

                // log errors here or whatever you're planning on doing
                alert(msg);
            }
            catch (err)
            {

            }
        };

Bearbeiten: Da stackes sich um eine Eigenschaft und nicht um eine Methode handelt, können Sie sie auch in älteren Browsern sicher aufrufen. Ich bin immer noch verwirrt, weil ich Error.prototypemir ziemlich sicher war, dass das Überprüfen für mich früher funktioniert hat und jetzt nicht mehr - also bin ich mir nicht sicher, was los ist.

Simon_Weaver
quelle
0

Wenn Sie console.error(e.stack)Firefox verwenden, wird nur die Stapelverfolgung in Protokollen angezeigt. Chrome zeigt auch die Meldung an. Dies kann eine schlechte Überraschung sein, wenn die Nachricht wichtige Informationen enthält. Protokollieren Sie immer beide.

Christophe Roussy
quelle
0

Probiere es einfach

throw new Error('some error here')

Dies funktioniert ziemlich gut für Chrom:

Geben Sie hier die Bildbeschreibung ein

Anthony Zhan
quelle