Suche…


Syntax

  • versuchen Sie {…} catch (error) {…}
  • versuche {…} endlich {…}
  • versuchen Sie {…} catch (error) {…} schließlich {…}
  • neuen Fehler werfen ([Nachricht]);
  • Fehler werfen ([Nachricht]);

Bemerkungen

try können Sie einen Codeblock definieren, der während der Ausführung auf Fehler getestet wird.

catch können Sie einen Codeblock definieren, der ausgeführt werden soll, wenn im try Block ein Fehler auftritt.

finally können Sie Code unabhängig vom Ergebnis ausführen. Beachten Sie jedoch, dass die Steuerflussanweisungen der try- und catch-Blöcke angehalten werden, bis die Ausführung des finally-Blocks abgeschlossen ist.

Interaktion mit Versprechen

6

Ausnahmen betreffen den synchronen Code, was die Zurückweisung von asynchronem Code verspricht . Wenn eine Ausnahme in einem Versprechenhandler ausgelöst wird, wird der Fehler automatisch abgefangen und stattdessen zum Versagen des Versprechens verwendet.

Promise.resolve(5)
    .then(result => {
        throw new Error("I don't like five");
    })
    .then(result => {
        console.info("Promise resolved: " + result);
    })
    .catch(error => {
        console.error("Promise rejected: " + error);
    });

Promise rejected: Error: I don't like five
7

Der Vorschlag für async-Funktionen, von dem erwartet wird, dass er Teil von ECMAScript 2017 ist, erweitert dies in die entgegengesetzte Richtung. Wenn Sie ein abgelehntes Versprechen erwarten, wird dessen Fehler als Ausnahme ausgelöst:

async function main() {
  try {
    await Promise.reject(new Error("Invalid something"));
  } catch (error) {
    console.log("Caught error: " + error);
  }
}
main();

Caught error: Invalid something

Fehlerobjekte

Laufzeitfehler in JavaScript sind Instanzen des Error Objekts. Das Error kann auch als Error verwendet werden oder als Basis für benutzerdefinierte Ausnahmen. Es ist möglich, jede Art von Wert (z. B. Zeichenfolgen) zu werfen. Es wird jedoch dringend empfohlen, Error oder eine seiner Ableitungen zu verwenden, um sicherzustellen, dass Debugging-Informationen wie Stapelverfolgungen ordnungsgemäß beibehalten werden.

Der erste Parameter für den Error Konstruktor ist die von Menschen lesbare Fehlermeldung. Sie sollten immer versuchen, eine nützliche Fehlernachricht anzugeben, wenn etwas schiefgegangen ist, selbst wenn zusätzliche Informationen an anderer Stelle verfügbar sind.

try {
   throw new Error('Useful message');
} catch (error) {
   console.log('Something went wrong! ' + error.message);
}

Reihenfolge der Operationen plus fortgeschrittene Gedanken

Ohne einen try-catch-Block werfen undefinierte Funktionen Fehler und stoppen die Ausführung:

undefinedFunction("This will not get executed");
console.log("I will never run because of the uncaught error!");

Wirft einen Fehler und führt die zweite Zeile nicht aus:

// Uncaught ReferenceError: undefinedFunction is not defined

Sie benötigen einen try-catch-Block, ähnlich wie andere Sprachen, um sicherzustellen, dass Sie den Fehler abfangen, damit der Code weiterhin ausgeführt werden kann:

try {
    undefinedFunction("This will not get executed");
} catch(error) {
    console.log("An error occured!", error);
} finally {
    console.log("The code-block has finished");
}
console.log("I will run because we caught the error!");

Nun haben wir den Fehler erkannt und können sicher sein, dass unser Code ausgeführt wird

// An error occured! ReferenceError: undefinedFunction is not defined(…)
// The code-block has finished
// I will run because we caught the error!

Was ist, wenn ein Fehler in unserem Fangblock auftritt?

try {
    undefinedFunction("This will not get executed");
} catch(error) {
    otherUndefinedFunction("Uh oh... ");
    console.log("An error occured!", error);
} finally {
    console.log("The code-block has finished");
}
console.log("I won't run because of the uncaught error in the catch block!");

Wir werden den Rest unseres Fangblocks nicht verarbeiten, und die Ausführung wird bis auf den finally-Block angehalten.

// The code-block has finished
// Uncaught ReferenceError: otherUndefinedFunction is not defined(…)

Sie könnten Ihre Try-Catch-Blöcke immer verschachteln. Sie sollten dies jedoch nicht tun, da dies extrem unordentlich wird.

try {
    undefinedFunction("This will not get executed");
} catch(error) {
    try {
        otherUndefinedFunction("Uh oh... ");
    } catch(error2) {
        console.log("Too much nesting is bad for my heart and soul...");
    }
    console.log("An error occured!", error);
} finally {
    console.log("The code-block has finished");
}
console.log("I will run because we caught the error!");

Fängt alle Fehler des vorherigen Beispiels ab und protokolliert Folgendes:

//Too much nesting is bad for my heart and soul...
//An error occured! ReferenceError: undefinedFunction is not defined(…)
//The code-block has finished
//I will run because we caught the error!

Wie können wir also alle Fehler auffangen? Für undefinierte Variablen und Funktionen: Das geht nicht.

Sie sollten auch nicht jede Variable und Funktion in einen try / catch-Block einschließen, da dies einfache Beispiele sind, die nur einmal vorkommen, bis Sie sie reparieren. Bei Objekten, Funktionen und anderen Variablen, von denen Sie wissen, dass sie vorhanden sind, Sie jedoch nicht wissen, ob deren Eigenschaften oder Unterprozesse oder Nebeneffekte vorhanden sind, oder Sie unter bestimmten Umständen einige Fehlerzustände erwarten, sollten Sie die Fehlerbehandlung abstrahieren auf irgendeine Art und Weise. Hier ist ein sehr einfaches Beispiel und Implementierung.

Ohne geschützte Methode zum Aufrufen von nicht vertrauenswürdigen oder ausnahmebedingten Methoden:

function foo(a, b, c) {
    console.log(a, b, c);
    throw new Error("custom error!");
}
try {
    foo(1, 2, 3);
} catch(e) { 
    try {
        foo(4, 5, 6); 
    } catch(e2) {
        console.log("We had to nest because there's currently no other way...");
    }
    console.log(e);
}
// 1 2 3
// 4 5 6
// We had to nest because there's currently no other way...
// Error: custom error!(…)

Und mit Schutz:

function foo(a, b, c) {
    console.log(a, b, c);
    throw new Error("custom error!");
}
function protectedFunction(fn, ...args) {
    try {
        fn.apply(this, args);
    } catch (e) {
        console.log("caught error: " + e.name + " -> " + e.message);
    }
}

protectedFunction(foo, 1, 2, 3);
protectedFunction(foo, 4, 5, 6);

// 1 2 3
// caught error: Error -> custom error!
// 4 5 6
// caught error: Error -> custom error!

Wir fangen Fehler und verarbeiten trotzdem den gesamten erwarteten Code, allerdings mit einer etwas anderen Syntax. So oder so funktioniert es, aber wenn Sie fortschrittlichere Anwendungen erstellen, sollten Sie darüber nachdenken, wie Sie die Fehlerbehandlung abstrahieren können.

Fehlertypen

In JavaScript gibt es sechs spezifische Kernfehlerkonstruktoren:

  • EvalError - erstellt eine Instanz, die einen Fehler darstellt, der in Bezug auf die globale Funktion eval() auftritt.

  • InternalError - erstellt eine Instanz, die einen Fehler darstellt, der auftritt, wenn ein interner Fehler in der JavaScript-Engine ausgelöst wird. ZB "zu viel Rekursion". (Nur von Mozilla Firefox unterstützt )

  • RangeError - erstellt eine Instanz, die einen Fehler darstellt, der auftritt, wenn eine numerische Variable oder ein Parameter außerhalb des gültigen Bereichs liegt.

  • ReferenceError - erstellt eine Instanz, die einen Fehler darstellt, der beim Dereferenzieren einer ungültigen Referenz auftritt.

  • SyntaxError - erstellt eine Instanz, die einen Syntaxfehler darstellt, der beim Analysieren von Code in eval() auftritt.

  • TypeError - erstellt eine Instanz, die einen Fehler darstellt, der auftritt, wenn eine Variable oder ein Parameter keinen gültigen Typ hat.

  • URIError - erstellt eine Instanz, die einen Fehler darstellt, der auftritt, wenn encodeURI() oder decodeURI() ungültige Parameter übergeben werden.

Wenn Sie einen Fehlerbehandlungsmechanismus implementieren, können Sie überprüfen, welche Art von Fehlern Sie vom Code abfangen.

try {
    throw new TypeError();
}
catch (e){
    if(e instanceof Error){
        console.log('instance of general Error constructor');
    }

    if(e instanceof TypeError) {
        console.log('type error');
    }
}

In diesem Fall ist e eine Instanz von TypeError . Alle Fehlertypen erweitern den Basiskonstruktor Error , daher ist es auch eine Instanz von Error .

Wenn man das bedenkt, zeigt uns, dass das Überprüfen von e als Error in den meisten Fällen nutzlos ist.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow