🌐 Lehrpfad 2: Moderne Datenmodelle & OOP

JS 08: Fehlerbehandlung & Debugging

Schreibe robusten und defensiven JavaScript-Code mit try/catch/finally, benutzerdefinierten Fehler-Klassen und instanceof.

🛑 1. Das try...catch...finally Kontrollmuster

Laufzeitfehler bringen ungesicherte Programme sofort zum Absturz. Mit try...catch fängst du Ausnahmen sicher ab und ermöglichst deiner Webanwendung eine kontrollierte Fehlerbehandlung:

try {
  // 1. Code ausführen, der fehlschlagen könnte:
  const daten = JSON.parse(roheEingabe);
  verarbeite(daten);
} catch (error) {
  // 2. Wird nur ausgeführt, wenn im try-Block ein Fehler aufgetreten ist:
  console.error("Fehler aufgetreten:", error.name, error.message);
} finally {
  // 3. Wird IMMER ausgeführt (z. B. für Aufräumarbeiten, Lade-Spinner stoppen):
  schliesseLadeAnzeige();
}

📊 Kontrollfluss-Diagramm

1. try { ... } (Code ausführen)
↓ Tritt Fehler auf?
✅ Nein: Normal weiter
❌ Ja: catch(err) { ... }
↓
3. finally { ... } (Aufräumen – läuft immer!)

💣 2. Fehler werfen mit throw & Eigene Error-Klassen

Mit dem throw-Befehl löst du gezielt Fehler aus. Statt generischer Strings wirft man in professionellem JavaScript immer Instanzen von Error (oder abgeleiteten Klassen):

// Basisklasse für alle Domänenfehler der App:
class AnwendungsFehler extends Error {
  constructor(message) {
    super(message);
    this.name = "AnwendungsFehler";
  }
}

// Spezifische Kindklasse mit Zusatzinformationen:
class ValidierungsFehler extends AnwendungsFehler {
  constructor(message, feld = null) {
    super(message);
    this.name = "ValidierungsFehler";
    this.feld = feld; // Zusätzliche Metadaten für das UI-Highlighting
  }
}
🪂 Didaktische Analogie: Die Notbremse & der Auffang-Fallschirm

Einen Fehler mit throw new ValidierungsFehler() zu werfen, ist wie das Ziehen der Sicherheits-Notbremse im fahrenden Zug: Der normale Ablauf stoppt sofort. Der catch-Block ist der Auffang-Fallschirm, der den Sturz abfedert und dafür sorgt, dass die Passagiere (deine Web-App-Benutzer) sicher landen, statt ins Nichts abzustürzen. Der finally-Block ist die Landestation, die in jedem Fall erreicht wird.

🧠 Diagnostischer Selbst-Check

Überprüfe dein Verständnis der Kernkonzepte und typischen Denkfallen, bevor du den Code in der Web-IDE schreibst.

🎯 3. Fehlerarten gezielt unterscheiden mit instanceof

Im catch-Block können unterschiedliche Fehlerarten auftreten. Mit dem instanceof-Operator kannst du gezielt auf Validierungsfehler anders reagieren als auf System- oder Netzwerkfehler:

try {
  sendeZahlung(konto, 500);
} catch (error) {
  if (error instanceof GuthabenFehler) {
    zeigeNutzerHinweis(`Nicht genügend Guthaben! Es fehlen ${error.betrag - error.saldo} €.`);
  } else if (error instanceof ValidierungsFehler) {
    markiereFormularFeldRot(error.feld, error.message);
  } else {
    // Unbekannter Systemfehler -> Erneut werfen oder an Monitoring-Service melden:
    throw error;
  }
}

📑 4. Cheat-Sheet: Error Handling & Debugging

Befehl / Syntax Beispiel Wirkung
throw new Error(...) throw new Error("Ungültig!"); Löst Ausnahme aus und bricht aktuellen Stack ab
try { } catch(e) { } try { ... } catch (e) { ... } Fängt Laufzeitfehler ab und verhindert Crash
finally { } finally { cleanup(); } Wird garantiert ausgeführt (mit oder ohne Fehler)
class X extends Error class MeinFehler extends Error { } Eigene typisierte Fehlerklasse mit Stacktrace
err instanceof X if (e instanceof ValidierungsFehler) Prüft die Fehlerklasse zur differenzierten Behandlung

🎯 5. Aufgaben & Checkliste in aufgabe.js

💡 Tipp für Teilziel 3

In parseBenutzerJson kannst du JSON.parse(jsonString) in einem inneren try...catch-Block aufrufen. Fange den SyntaxError ab und wirf stattdessen einen new ValidierungsFehler(..., "jsonString")!

💻 In Web-IDE öffnen → ← Zurück zu JS 07 Weiter zu Lehrpfad 3 (Async) →