JavaScript-Anti-Silent-Techniken zur Anzeige von Fehlern
-
16-09-2020 - |
Frage
Was wäre eine gute Möglichkeit, Fehler in JavaScript zu melden, anstatt sich auf Nullen und Undefinierte zu verlassen, wenn Fehler auftreten und eine Funktion nicht fortfahren kann?Mir fallen drei Ansätze ein:
- nichts tun
- eine Ausnahme auslösen
- behaupten
Hier ist ein einfaches Beispielszenario – eine Funktion, die einem Benutzerkonto den eingegebenen Betrag gutschreibt.Die Funktion credit
ist Teil eines Account
Objekt.
Hier ist die naive Lösung.
function credit(amount) {
this.balance += amount;
}
Ein großes Problem bei diesem Ansatz sind ungültige Daten.Lassen Sie uns das Problem beheben und einen Rückgabewert verwenden, um anzugeben, dass der Vorgang fehlgeschlagen ist.
function credit(amount) {
if(!isInt(amount)) {
return false;
}
this.balance += amount;
}
Dies stellt eine Verbesserung gegenüber der vorherigen dar, der Clientcode muss jedoch den Rückgabewert überprüfen, um sicherzustellen, dass der Vorgang erfolgreich war.Dies für grundsätzlich jede Methode im System durchzuführen, kann umständlich sein.
if(!johnDoe.credit(100)) {
// do some error handling here
}
Ein dritter Ansatz, der dem zweiten ähnelt, besteht darin, eine Ausnahme auszulösen.Da wir die Ausnahme selbst auslösen, könnte es sich um eine bestimmte Art von Ausnahme handeln und nicht um eine allgemeine.
function credit(amount) {
if(!isInt(amount)) {
throw new InvalidAmountError(amount);
}
this.balance += amount;
}
Ein vierter Ansatz, der dem Auslösen von Ausnahmen ähnelt, besteht darin, Zusicherungen in Ihrem Code zu verwenden.Ein Nachteil im Vergleich zum obigen Ansatz besteht darin, dass wir aufgrund der generischen Assertion die Möglichkeit verlieren, benutzerdefinierte Ausnahmen auszulösen.Es ist jedoch immer noch möglich, das auszulösende Objekt bei jedem Assert-Aufruf zu übergeben.
function credit(amount) {
assert(!isInt(amount), "Amount to credit is not an integer");
this.balance += amount;
}
Eine globale assert
Die Funktion ist einfach zu schreiben und macht den Code etwas kürzer.
function assert(value, message) {
if(value !== true) {
throw new AssertionError(message);
}
}
function AssertionError(message) {
this.message = message;
}
AssertionError.prototype.toString = function() {
return 'AssertionError: ' + this.message;
}
Welche dieser Ansätze wären ein guter Weg, um mit unerwarteten Werten und unglücklichen Wegen umzugehen?Gibt es andere, hier nicht erwähnte Ansätze, die nützlich sein könnten?
Lösung
Erwägen Sie ein clientseitiges Protokollierungsframework, um Fehler zu melden, z Log4js.Abhängig von der Anwendung kann man Nachrichten (z. B. Informationen, Debug, Warnungen, Fehler) im Browser protokollieren oder über Ajax an den Server weiterleiten.
Die Log4js-Site bietet auch eine Liste anderer JavaScript-Protokollierungsframeworks.
Ein guter Ansatz unter Verwendung Ihres benutzerdefinierten Ausnahmebeispiels wäre, die Ausnahme auszulösen und den Fehler nach eigenem Ermessen zu protokollieren.
Andere Tipps
Ein Mangel im Vergleich zum oben genannten Ansatz ist, dass wir, da die Behauptung allgemein ist, die Fähigkeit verlieren, benutzerdefinierte Ausnahmen zu veröffentlichen
Nicht unbedingt:
function assert(value,message,Exctype) {
if(value !== true) throw new Exctype(message);
}
Konstruktoren sind Funktionen.Funktionen sind erstklassige Werte.Geben Sie sie ruhig weiter.