660 Stimmen

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

Wenn ich selbst eine JavaScript-Ausnahme auslöse (z. B., throw "AArrggg" ), wie kann ich den Stack-Trace (in Firebug oder anders) erhalten? Im Moment bekomme ich nur die Meldung.

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

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

Wenn foo aufgerufen wird, möchte ich eine Stapelverfolgung erhalten, die die Aufrufe an foo , bar , bar .

1voto

unsynchronized Punkte 4729

Ich bin zwar etwas spät dran, aber hier ist eine andere Lösung, die Automatische Erkennung wenn arguments.callee verfügbar ist, und verwendet andernfalls new Error().stack. Getestet in Chrome, 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 aus unter http://jsfiddle.net/qcP9y/6/

// 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();

0voto

Simon_Weaver Punkte 129442

Wow - ich habe in den letzten 6 Jahren niemanden gesehen, der vorgeschlagen hätte, zuerst zu prüfen, ob stack verfügbar ist, bevor Sie es verwenden! Das Schlimmste, was Sie in einem Error-Handler tun können, ist, einen Fehler auszulösen, weil Sie etwas aufrufen, das nicht existiert.

Wie andere gesagt haben, während stack ist in den meisten Fällen sicher zu verwenden, wird aber in IE9 oder früher nicht unterstützt.

Ich protokolliere meine unerwarteten Fehler und ein Stack-Trace ist ziemlich wichtig. Für maximale Unterstützung prüfe ich zunächst, ob Error.prototype.stack existiert und eine Funktion ist. Wenn dies der Fall ist, 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)
            {

            }
        };

Edit : Es scheint, dass seit stack eine Eigenschaft und keine Methode ist, können Sie sie auch in älteren Browsern sicher aufrufen. Ich bin immer noch verwirrt, weil ich ziemlich sicher war, dass die Überprüfung Error.prototype hat bei mir früher funktioniert und jetzt nicht mehr - ich bin mir also nicht sicher, was da los ist.

0voto

Christophe Roussy Punkte 15183

使用方法 console.error(e.stack) Firefox zeigt nur den Stacktrace in den Protokollen an, Chrome zeigt die Meldung ebenfalls an. Das kann eine böse Überraschung sein, wenn die Meldung wichtige Informationen enthält. Loggen Sie immer beides.

0voto

kirilv Punkte 1345

Ich musste eine endlose Rekursion in smartgwt mit IE11 untersuchen, also brauchte ich einen Stack-Trace, um das genauer zu untersuchen. Das Problem war, dass ich nicht in der Lage war, die Dev-Konsole zu verwenden, da die Reproduktion auf diese Weise schwieriger war.
Verwenden Sie das Folgende in einer Javascript-Methode:

try{ null.toString(); } catch(e) { alert(e.stack); }

0voto

Michael Punkte 1548

Es ist einfacher, einen Stack-Trace auf Firefox zu erhalten als auf IE, aber im Grunde ist es das, was Sie tun wollen:

Wickeln Sie den "problematischen" Teil des Codes 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, aus der das Problem stammt e.lineNumber : Die Zeilennummer in der Datei/Seite, in der das Problem aufgetreten ist e.message : Eine einfache Meldung, die beschreibt, welche Art von Fehler aufgetreten ist e.name : Die Art des aufgetretenen Fehlers, im obigen Beispiel sollte dies 'TypeError' sein e.stack : Enthält den Stack-Trace, der die Ausnahme verursacht hat

Ich hoffe, das hilft Ihnen weiter.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X