53 Stimmen

Wie man Ausnahmen in JavaScript protokolliert

Als C#-Entwickler bin ich an folgenden Stil der Ausnahmebehandlung gewöhnt:

try
{
    throw SomeException("hahahaha!");
}
catch (Exception ex)
{
    Log(ex.ToString());
}

Ergebnis
------

SomeNamespace.SomeException: hahahaha!
    at ConsoleApplication1.Main() in ConsoleApplication1\Program.cs:line 27

Es ist wirklich einfach und sagt mir dennoch alles, was ich über die Ausnahme wissen muss und wo sie aufgetreten ist.

Wie erreiche ich das Äquivalent in JavaScript, wo das Ausnahmeobjekt selbst nur ein String sein könnte? Ich möchte wirklich in der Lage sein, die genaue Codezeile zu kennen, an der die Ausnahme aufgetreten ist. Allerdings protokolliert der folgende Code überhaupt nichts Nützliches:

try
{
    var WshShell = new ActiveXObject("WScript.Shell");
    return WshShell.RegRead("HKEY_LOCAL_MACHINE\\Some\\Invalid\\Location");
}
catch (ex)
{
    Log("Ausnahme abgefangen: " + ex);
}

Ergebnis
------

Ausnahme abgefangen: [object Error]

BEARBEITEN (erneut): Nur um es klarzustellen, dies ist für interne Anwendung, die intensiv JavaScript verwendet. Ich suche nach einem Weg, nützliche Informationen aus JavaScript-Fehlern zu extrahieren, die im Produktionssystem auftreten können - ich habe bereits einen Protokollierungsmechanismus, möchte nur einen Weg finden, einen sinnvollen String zum Protokollieren zu erhalten.

66voto

Nacho Coloma Punkte 6519

Sie haben nicht angegeben, ob Sie im Browser oder auf dem Server arbeiten. Wenn es ersteres ist, gibt es eine neue console.error-Methode und die e.stack-Eigenschaft:

try {
    // Mach etwas Verrücktes
} catch (e) {
    console.error(e, e.stack);
}

Bitte beachten Sie, dass error in Firefox und Chrome funktioniert, aber nicht standardisiert ist. Ein schnelles Beispiel, das auf console.log zurückgreift und e protokolliert, wenn kein e.stack vorhanden ist:

try {
    // Mach etwas Verrücktes
} catch (e) {
    (console.error || console.log).call(console, e.stack || e);
}

2 Stimmen

Der einzige Browser, der kein e.stack hat, ist der IE 9 und älter - sie machen weniger als 2% des Browser-Marktanteils gemäß Net Marketshare aus. Ich werde mich sicherlich nicht darum kümmern, diese Browser zu unterstützen - Microsoft hat den erweiterten Support für IE 8 vor vielen Jahren eingestellt, also habe ich keine Ahnung, wer es noch benutzt.

0 Stimmen

IE9 ist jetzt seit mehr als einem Jahrzehnt alt, und Microsoft hat die Unterstützung vollständig eingestellt.

29voto

user1147862 Punkte 3896

Wie Eldar anmerkt, können Sie e.message verwenden, um die Nachricht der Ausnahme zu erhalten. Allerdings können Sie in Chrome, Firefox und IE10+ auch den Stack-Trace mit e.stack abrufen. Der Stack-Trace wird die Datei und Zeilennummer der Ausnahme enthalten.

Also, um einen String mit Ausnahmeinformationen zusammenzustellen, würden Sie etwas Ähnliches wie dies schreiben:

var exmsg = "";
if (e.message) {
    exmsg += e.message;
}
if (e.stack) {
    exmsg += ' | stack: ' + e.stack;
}

Beachten Sie, dass Sie nur einen Stack-Trace erhalten, wenn

  1. die Ausnahme vom Browser geworfen wurde (z.B. als Reaktion auf einen Syntaxfehler);
  2. das Ausnahmeobjekt ein Error-Objekt ist oder das Error-Objekt als Prototyp hat.

Also, einfach nur einen String zu werfen (throw 'Ausnahme!!') wird Ihnen keinen Stack-Trace geben.

Um dies etwas weiter zu führen, um alle unbehandelten Ausnahmen abzufangen, würden Sie einen window.onerror-Handler verwenden (ähnlich dem .Net Application_Error-Handler in global.asax). Der Nachteil war früher (und ist größtenteils immer noch), dass Ihnen dadurch kein Zugriff auf das tatsächliche Ausnahmeobjekt gegeben wurde, sodass Sie den Stack-Trace nicht erhalten konnten. Sie bekamen nur die Nachricht, URL und Zeilennummer.

In letzter Zeit wurde der Standard erweitert, um Ihnen auch die Spalte (großartig für minifizierte Dateien) und das Ausnahmeobjekt zu geben: http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#errorevent

Aktuell (April 2014) implementiert nur Chrome 32 all dies. IE10+ gibt Ihnen die Spalte, aber nicht das Ausnahmeobjekt. Firefox 28 gibt immer noch nur die Nachricht, URL und Zeilennummer zurück. Hoffentlich wird sich das bald verbessern. Ich habe darüber für das JSNLog-Projekt geschrieben, unter: http://jsnlog.com/Documentation/GetStartedLogging/ExceptionLogging

(Haftungsausschluss: Ich bin der Autor von JSNLog und jsnlog.com)

Zweitens unterstützt das .Net Exception-Objekt innere Ausnahmen. Es hat auch eine Daten-Eigenschaft, sodass Sie Schlüssel-Wert-Paare mit z. B. Variablenwerten anhängen können. So etwas habe ich im JavaScript-Fehlerobjekt vermisst, also habe ich mein eigenes Exception-Objekt erstellt, auch als Teil des JSNLog-Projekts. Es befindet sich in der jsnlog.js-Datei im jsnlog.js-GitHub-Projekt (https://github.com/mperdeck/jsnlog.js).

Die Beschreibung finden Sie unter: http://jsnlog.com/Documentation/JSNLogJs/Exception

Zu guter Letzt eine schamlose Eigenwerbung - das JSNLog-Projekt, an dem ich arbeite, ermöglicht es Ihnen, Logger in Ihrem JavaScript einzufügen und die Protokollnachrichten automatisch in Ihr vorhandenes serverseitiges Protokoll einzufügen. Um JavaScript-Ausnahmen mit ihren Stack-Traces in Ihr serverseitiges Protokoll zu protokollieren, müssen Sie nur Folgendes schreiben:

try {
    ...
} catch (e) {
    JL().fatalException("Etwas ist schief gelaufen!", e);
}

0 Stimmen

Ich weiß, dass ich 3 Jahre zu spät zur Party komme.... aber ich bin mir ziemlich sicher, dass man den Stack-Trace erhält, wenn man eine tatsächliche Ausnahme wirft (nicht nur einen String). So zum Beispiel: throw new Exception('Ausnahme!!');.

16voto

Eldar Djafarov Punkte 21419

Sie können es fast auf die gleiche Weise verwenden.

versuchen
{
    throw new Error("hahahaha!");
}
fangen (e)
{
    alert(e.message)
}

Aber wenn Sie die Zeilennummer und den Dateinamen erhalten möchten, an denen der Fehler ausgelöst wird, vermute ich, dass es keine plattformübergreifende Lösung gibt. Nachricht und Name sind die einzigen Standardproperties des Error-Objekts. In Mozilla gibt es auch die Eigenschaften lineNumber und fileName.

1 Stimmen

Das funktioniert nicht auf Serverseite. Außerdem ist es nicht modernes UX.

4voto

mahju Punkte 1161

Ich bin mir nicht sicher, ob es sich um einen Browserübergreifenden Fehler handelt oder ob es das ist, wonach Sie suchen, aber ich empfehle Ihnen, es zu versuchen:

window.onerror = function (err, file, line) {
    logError('Folgender Fehler ist aufgetreten: ' + 
    err + '\nIn Datei: ' + file + '\nIn Zeile: ' + line);
    return true;
}

3voto

Rahul Makhija Punkte 311

Ich hatte ein ähnliches Problem.

Die Verwendung von console.table(error); hat bei mir gut funktioniert. Es zeigt Informationen in einer Tabelle an und ermöglicht es mir auch, sie zu erweitern/zusammenzuklappen, um weitere Details zu sehen.

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