Was sind die Best Practices für die Behandlung von JavaScript-Fehlern?

137

Ich bin auf der Suche zu beginnen mein JavaScript ein bisschen mehr Fehler Beweis zu machen, und ich bin viel Dokumentation finden , über die Verwendung try, catch, finallyund throw, aber ich bin nicht eine Tonne Rat von Experten auf der Suche nach, wann und wo Fehler zu werfen.

  • Sollte jeder Code in einen Versuch / Fang eingewickelt werden?
  • Gibt es weitere Ratschläge wie diesen, an welchem ​​Punkt Fehler abgefangen werden sollten?
  • Gibt es Nachteile beim Auslösen von Fehlern, anstatt dass Code in der Produktion stillschweigend ausfällt?
  • Dies wurde in Bezug auf Implementierungen auf SO angesprochen, aber sind JS-Fehler bei der Serverprotokollierung eine wirksame Strategie?
  • Was sollte ich sonst noch über das Einfangen von Fehlern in meiner Anwendung wissen?

Ich bin auch ein absolutes Spiel, um von Büchern zu hören, die großartige Kapitel oder ausführliche Erklärungen zur Fehlerbehandlung enthalten. Eloquentes JavaScript geht auf die Angelegenheit ein, ist jedoch in Bezug auf das Problem nicht sehr präskriptiv oder unvoreingenommen.

Vielen Dank für jeden Rat, den Sie geben können!

Joshua Cody
quelle
Es hängt sicherlich davon ab, wie spektakulär Sie versagen, wenn etwas schief geht, und von der Menge möglicher Fehlermeldungen. Sie möchten nicht scheitern, weil Ihr Fehlerprotokollierungsverzeichnis jetzt voll ist, oder? - Hast du überhaupt hier geschaut? stackoverflow.com/search?q=error+logging+javascript
mplungjan
@mplungjan - Ich habe die Antworten dort gescannt, aber nicht viel schien kanonisch, und die Suche nach Best Practices für die Behandlung von Javascript-Fehlern / Ausnahmen ergab nichts. Daher dachte ich, es könnte hilfreich sein, einige komprimierte Gedanken zu erbitten, sowohl für meine eigenes Verständnis und zukünftige Suchende. Vielleicht ist dies ein Thema, bei dem die Verschreibung von Best Practices nicht so gut wie möglich ist, aber jede Situation sehr einzigartig ist?
Joshua Cody
1
"Sollte jeder Code in einen Versuch / Fang eingewickelt werden?" Natürlich nicht. Es gibt viele Codes, von denen Sie wissen, dass sie immer funktionieren (vorausgesetzt, Sie testen sie natürlich, aber der Sinn von try / catch besteht nicht darin, Codierungsfehler zu fangen oder zu beschönigen). Nur Wrap-Code, der manchmal aufgrund von etwas außerhalb seiner Kontrolle fehlschlägt, im Allgemeinen aufgrund von Ressourcenzugriff usw. Hinweis: Einige Dinge, die fehlschlagen können, verfügen über eine integrierte Fehlerbehandlung, z. B. würde ich Ajax nicht von Grund auf neu codieren, wenn Es gibt viele Bibliotheken, die dies tun, um browserübergreifende Probleme zu lösen und eine Fehlerbehandlungsfunktion anzugeben.
nnnnnn
1
Das ist eine gute Frage, Josh, +1. Viele syntaktische Ratschläge, aber wie Sie sagen, das ist der einfache Teil. In der Antwort dieser Frage ( stackoverflow.com/questions/2825427/… ) wird darauf hingewiesen , dass Ausnahmen in JS nicht so häufig verwendet werden und Gründe angegeben werden.
Whitneyland

Antworten:

63

Eine immens interessante Reihe von Folien zur Behandlung von JavaScript-Fehlern in Unternehmen finden Sie unter http://www.devhands.com/2008/10/javascript-error-handling-and-general-best-practices/

Kurz gesagt, es fasst zusammen:

  1. Angenommen, Ihr Code schlägt fehl
  2. Protokollieren Sie Fehler auf dem Server
  3. Sie, nicht der Browser, behandeln Fehler
  4. Identifizieren Sie, wo Fehler auftreten können
  5. Wirf deine eigenen Fehler
  6. Unterscheiden Sie zwischen schwerwiegenden und nicht schwerwiegenden Fehlern
  7. Stellen Sie einen Debug-Modus bereit

Die Folien gehen viel detaillierter und geben Ihnen höchstwahrscheinlich eine Richtung.

AKTUALISIEREN

Die oben erwähnte Präsentation finden Sie hier: http://www.slideshare.net/nzakas/enterprise-javascript-error-handling-presentation

cdmdotnet
quelle
24
Die Devhands-Verbindung ist unterbrochen.
Ryan Gates
7
Für diejenigen, die dies 2017 lesen, würde ich argumentieren, dass Sie von den Folien nicht viel Wert bekommen werden - diese Zusammenfassung gibt Ihnen 90% der Informationen. Es sind immer noch wertvolle Informationen. Prost!
Philippe Hebert
29

Nicholas Zakas von Yahoo! Bei Ajax Experience 2008 hielt Fame einen Vortrag über Enterprise Error Handling ( Folien ), in dem er Folgendes vorschlug:

function log(sev,msg) {
    var img = new Image();
    img.src = "log.php?sev=" +
        encodeURIComponent(sev) +
        "&msg=" + encodeURIComponent(msg);
}

// usage
log(1, "Something bad happened.")

// Auto-log uncaught JS errors
window.onerror = function(msg, url, line) {
    log(1, msg);
    return true;
}

Ein Jahr später veröffentlichte Nicholas Zakas ein Update in seinem Blog, das ein cleveres Muster enthielt, mit dem Fehlerbehandlungscode automatisch in Ihre Produktionsumgebung eingefügt werden kann (mithilfe einer aspektorientierten Programmierung).

Wenn Sie mit der Protokollierung von window.error-Aufrufen beginnen, werden Sie zwei Dinge bemerken:

  1. Wenn Ihre Site ziemlich komplex ist, werden Sie viele Fehler protokollieren
  2. Sie werden eine Reihe nutzloser "window.error in undefined: 0" -Nachrichten sehen

Das Reduzieren des Stroms von Protokolleinträgen ist so einfach wie das Testen des Schweregrads und / oder einer Zufallszahl, bevor Sie sich beim Server anmelden:

function log(sev,msg) {
    if (Math.random() > 0.1) return; // only log some errors

    var img = new Image();
    img.src = "log.php?sev=" +
        encodeURIComponent(sev) +
        "&msg=" + encodeURIComponent(msg);
}

Die Behandlung des nutzlosen Fehlers "window.error in undefined: 0" hängt von Ihrer Site-Architektur ab, kann jedoch versuchen, alle Ajax-Aufrufe zu identifizieren und eine Ausnahme auszulösen, wenn etwas fehlschlägt (möglicherweise wird eine Stapelverfolgung mit stacktrace.js zurückgegeben ).

Jens Roland
quelle
67
Ich weiß, dass dies eine alte Frage ist, aber es ist eine der schlimmsten Ideen, die ich je gehört habe, einige Fehler zufällig zu ignorieren.
jbabey
26
@jbabey: Für eine kleine Site haben Sie Recht, aber wenn Sie eine große Site mit 100.000 oder Millionen Benutzern betreiben, müssen Sie Ihre Server (oder das Internet) wirklich nicht mit redundanten Protokollierungsanforderungen überfluten. Auf einem ausreichend großen System tritt jeder echte Fehler zehntausend Mal am Tag auf, sodass diese Form der Begrenzung einwandfrei funktioniert. Die Idee wird tatsächlich bei Facebook umgesetzt.
Jens Roland
1
Protokollierungsfehler im Debugging-Modus sind wahrscheinlich genauso wichtig wie die Begrenzung von Produktionsfehlerberichten. Daher ist möglicherweise eine Lösung erforderlich, um diesen Wert zu verwalten und den Protokollierungsschwellenwert zu begrenzen.
Frattaro
2
@NickBull Ich habe 2011-2012 eine Reihe von Facebooks JavaScript-Modulen rückentwickelt. dort habe ich es gefunden.
Jens Roland
1
@ NickBull hat gerade meine alten Dateien überprüft und hatte diese noch. Ich habe diesen Trick im Facebook-Bootloader-Modul gefunden: if (global.logJSError) if (Math.random() < .01) logJSError('bootloader', {(Zugegeben, dieser Code drosselt nicht alle Fehler, sondern nur eine bestimmte Klasse von Timeout-Fehlern)
Jens Roland
7

IHMO, Sie sollten die Fehlerbehandlung in Javascript wie in mehreren anderen Sprachen (AFAIK: Python, Java) verwenden.

Für eine bessere Lesbarkeit (und wahrscheinlich eine bessere Leistung, obwohl ich nicht sicher bin, ob dies einen wirklich großen Einfluss hat) sollten Sie den try / catch-Block hauptsächlich in den folgenden Fällen verwenden:

  • Der Teil des Codes, den Sie umbrechen möchten, ist ein wichtiger Teil des gesamten Algorithmus . Wenn es fehlschlägt, könnte es:

    • Erstellen Sie Fehler im nächsten Teil der Codes (z. B. weil eine Variable fehlt ...)
    • Stellen Sie sicher, dass die Seite nicht wie erwartet aussieht (Auswirkungen auf Inhalt oder CSS).
    • die Ergebnisse für den Benutzer seltsam erscheinen lassen (Auswirkungen auf das Codeverhalten)
  • Sie wissen, dass der Code, den Sie schreiben, nicht mit jedem Browser kompatibel ist

  • Sie haben geplant, dass der Code möglicherweise fehlschlägt (da es keine andere Möglichkeit gibt, zu überprüfen, ob er funktioniert, wenn ... dann ... blockiert).
  • Und auch, wenn Sie debuggen möchten, ohne den Endbenutzer zu stören

Möglicherweise haben Javascript-Experten andere Elemente zu geben.

meine 2 Cent auf die Box,

Grüße,

Max

JMax
quelle
1
"Der Teil des Codes, den Sie umbrechen möchten, ist ein wichtiger Teil des gesamten Algorithmus" - hängt möglicherweise davon ab, wie Sie den Fehler behandeln möchten. Wenn Sie wissen, dass es bei einem Fehler keine Möglichkeit gibt, mit dem Algorithmus fortzufahren, ist es möglicherweise besser, das Ganze in einen Versuch / Fang zu packen, denn wenn Ihr Versuch / Fang (z. B.) in verschachtelten Schleifen vergraben ist, ist dies eher ein Leistungseinbruch . Wenn Sie jedoch in Ausnahmefällen Maßnahmen ergreifen und mit dem Algorithmus fortfahren können, benötigen Sie ein detaillierteres Try / Catch-Setup.
nnnnnn
5

Zusätzlich zu den anderen Antworten: Eine wichtige Sache ist die Verwendung von Kontextdaten, die in JavaScript-Fehlerobjekten und in den window.onerrorFunktionsparametern verfügbar sind .

Dinge wie der Stacktrace (errorObject.stack), der Dateiname, die Zeilennummer und die Spaltennummer. Beachten Sie, dass jeder Browser einige Unterschiede aufweist. Versuchen Sie also nach besten Kräften, nette Fehler zu erhalten.

Es kann sogar Probleme mit dem Konsolenobjekt selbst geben . Ich verwende eine benutzerdefinierte window.onerror-Funktion, die von dieser inspiriert ist, und eine spezielle Funktion, um ein bestimmtes Standardfehlerobjekt zu verfolgen, das von diesem Code inspiriert ist .

Ein weiterer guter Punkt ist, die Version Ihrer Webanwendung irgendwo in der Nähe des Stacktraces einzuschließen (zum schnellen und sicheren Kopieren und Einfügen). Möglicherweise werden Fehler im Entwicklungsmodus auch aggressiver angezeigt (Warnung ...), da Entwickler die Browserkonsole nicht ständig überwachen und einige der Probleme möglicherweise nicht sehen.

Verwenden Sie auch vermeiden throw 'My message', verwenden throw new Error('My message'), können Sie sogar benutzerdefinierte Fehler haben, lesen Sie diesen Artikel .

Fügen Sie den Fehlern immer einen Kontext hinzu (die Version, die ID des Objekts, eine benutzerdefinierte Nachricht, ...) und stellen Sie außerdem sicher, dass Sie zwischen externen Fehlern (einige externe Daten oder Umstände haben Ihr System zum Ausfall gebracht) und internen Fehlern unterscheiden / assertions (Ihr eigenes System ist durcheinander), lesen Sie über ' Design by Contract '.

Hier ist eine Anleitung .

Denken Sie auch an die Verwendung einer allgemeinen Fehlerbehandlung wie Interceptors für Ihre Bibliotheken und Frameworks:

Christophe Roussy
quelle