Kurz: Fehler gehören zum Programmieren dazu. Mit try/catch fängst du sie ab, damit das Programm nicht abstürzt.
Teil des Kurses JavaScript
Kapitel 22 von 40 im Kurs JavaScript. Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.
Fehler gehören zum Programmieren dazu. Mit try/catch fängst du sie ab, damit das Programm nicht abstürzt.
try, catch, finally
try {
console.log("vorher");
JSON.parse("{kaputt");
console.log("wird nie erreicht");
} catch (fehler) {
console.log("Fehler:", fehler.name);
} finally {
console.log("läuft immer");
}
console.log("Programm läuft weiter");Ausgabe:
vorher
Fehler: SyntaxError
läuft immer
Programm läuft weitertry: Code, der fehlschlagen kanncatch: läuft nur bei einem Fehler;fehlerist das Fehlerobjektfinally: läuft immer (Aufräumen: Dateien schließen, Ladeanzeige ausblenden)
Das Error-Objekt
try {
null.eigenschaft;
} catch (e) {
console.log(e.name);
console.log(e.message);
console.log(e instanceof TypeError, e instanceof Error);
console.log(e.stack.split("\n")[0]);
}Ausgabe:
TypeError
Cannot read properties of null (reading 'eigenschaft')
true true
TypeError: Cannot read properties of null (reading 'eigenschaft')Häufige Fehlertypen
| Typ | Ursache |
|---|---|
SyntaxError | ungültiger Code oder ungültiges JSON |
ReferenceError | Variable existiert nicht |
TypeError | falscher Typ, z. B. null.x oder Aufruf eines Nicht-Funktionswerts |
RangeError | Wert außerhalb des erlaubten Bereichs |
URIError, EvalError | selten |
const tests = [
() => unbekannteVariable,
() => (5)(),
() => new Array(-1),
() => "abc".repeat(-1),
() => JSON.parse("x"),
];
for (const t of tests) {
try { t(); } catch (e) { console.log(e.name + ": " + e.message); }
}Ausgabe:
ReferenceError: unbekannteVariable is not defined
TypeError: 5 is not a function
RangeError: Invalid array length
RangeError: Invalid count value: -1
SyntaxError: Unexpected token 'x', "x" is not valid JSONEigene Fehler auslösen
Mit throw löst du selbst Fehler aus:
function teile(a, b) {
if (b === 0) throw new RangeError("Division durch 0 ist nicht erlaubt");
return a / b;
}
try {
console.log(teile(10, 2));
console.log(teile(1, 0));
} catch (e) {
console.log(`${e.name}: ${e.message}`);
}Ausgabe:
5
RangeError: Division durch 0 ist nicht erlaubtWirf immer ein Error-Objekt (oder eine Unterklasse), nicht nur Text, denn nur so gibt es einen Stacktrace.
Eigene Fehlerklassen
class ValidierungsFehler extends Error {
constructor(feld, nachricht) {
super(nachricht);
this.name = "ValidierungsFehler";
this.feld = feld;
}
}
function pruefe(nutzer) {
if (!nutzer.name) throw new ValidierungsFehler("name", "Name fehlt");
if (nutzer.alter < 0) throw new ValidierungsFehler("alter", "Alter negativ");
return true;
}
for (const n of [{ name: "Mia", alter: 5 }, { alter: 3 }, { name: "Tom", alter: -1 }]) {
try {
console.log(pruefe(n));
} catch (e) {
if (e instanceof ValidierungsFehler) console.log(`${e.feld}: ${e.message}`);
else throw e; // unbekannte Fehler weiterreichen
}
}Ausgabe:
true
name: Name fehlt
alter: Alter negativFehlerursache mitgeben
try {
try {
JSON.parse("{");
} catch (original) {
throw new Error("Konfiguration ungültig", { cause: original });
}
} catch (e) {
console.log(e.message, "<-", e.cause.name);
}Ausgabe:
Konfiguration ungültig <- SyntaxErrorFehler in async-Code
In async-Funktionen fängst du Fehler mit try/catch rund um await, bei Promises mit .catch() (siehe nächste Kapitel). Ein try/catch um einen Timer-Callback fängt dessen Fehler nicht, weil der später und woanders läuft.
Defensiv programmieren
- Eingaben prüfen, bevor du sie benutzt
?.und??gegen fehlende Werte einsetzen- Fehler nicht stillschweigend verschlucken: mindestens loggen
- Nur Fehler fangen, die du auch behandeln kannst
Merke
try { } catch (e) { } finally { }fängt Fehler ab und räumt aufthrow new Error("Text")löst Fehler aus- Fehlertypen:
TypeError,ReferenceError,RangeError,SyntaxError - Eigene Fehler:
class X extends Error - Fehler nicht verschlucken, unbekannte weiterreichen
Übungsaufgabe
Schreibe eine Funktion leseZahl(text), die bei ungültiger Eingabe einen eigenen Fehler wirft, und fange ihn in einer Schleife über mehrere Eingaben ab.
Quiz zur Selbstkontrolle
Wann läuft der finally-Block?
- Immer, mit oder ohne Fehler (richtig)
- Nur bei einem Fehler
- Nur ohne Fehler
- Nie
Was ist besser als throw "Text"?
- throw new Error(“Text”) (richtig)
- return “Text”
- console.log(“Text”)
- exit(“Text”)
Was löst null.name aus?
- Einen TypeError (richtig)
- Einen SyntaxError
- Einen RangeError
- Nichts
Weiter im Kurs
Zurück: Klassen und Objekte
Weiter: Module: import und export
Alle Kapitel: JavaScript im Überblick