EMZETT.
Login

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 weiter
  • try: Code, der fehlschlagen kann
  • catch: läuft nur bei einem Fehler; fehler ist das Fehlerobjekt
  • finally: 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

TypUrsache
SyntaxErrorungültiger Code oder ungültiges JSON
ReferenceErrorVariable existiert nicht
TypeErrorfalscher Typ, z. B. null.x oder Aufruf eines Nicht-Funktionswerts
RangeErrorWert außerhalb des erlaubten Bereichs
URIError, EvalErrorselten
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 JSON

Eigene 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 erlaubt

Wirf 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 negativ

Fehlerursache 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 <- SyntaxError

Fehler 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 auf
  • throw 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

Weiter im Kurs

Zurück: Klassen und Objekte

Weiter: Module: import und export

Alle Kapitel: JavaScript im Überblick