tutorials / javascript-error-handling

JavaScript Error Handling: Fehler sauber behandeln

Fehler passieren. Ob Tippfehler, falsche Benutzereingaben oder ein kaputtes Netzwerk: Ohne Error Handling wird aus einem kleinen Problem schnell ein kompletter Absturz. In diesem Tutorial lernst du, wie du Fehler kontrolliert behandelst, damit dein Code stabil und nachvollziehbar bleibt.

Warum Error Handling kein Bonus ist

Viele Einsteiger behandeln Fehler erst, wenn etwas kaputtgeht. Besser ist es, von Anfang an damit zu planen. Ein sauberer Umgang mit Fehlern bedeutet:

  • Nutzer bekommen verständliche Rückmeldungen statt kryptischer Meldungen.
  • Du erkennst schneller, wo ein Problem entsteht.
  • Dein Programm bleibt handlungsfähig, statt komplett abzubrechen.

try/catch/finally: Der Standard-Werkzeugkasten

Mit try/catch fängst du Fehler ab, die im try-Block passieren. finally läuft immer, egal ob ein Fehler auftritt oder nicht.

function parseJson(input) {
  try {
    const data = JSON.parse(input);
    return data;
  } catch (error) {
    console.error("Ungültiges JSON:", error.message);
    return null;
  } finally {
    console.log("Parsing-Versuch abgeschlossen.");
  }
}

parseJson('{"name": "Mia"}');
parseJson('oops');

Merke: catch fängt nur Fehler ab, die innerhalb des try-Blocks passieren.

Fehler gezielt werfen: throw + Error-Objekte

Nicht jeder Fehler kommt von selbst. Manchmal musst du bewusst abbrechen, wenn Eingaben ungültig sind. Dafür gibt es throw.

function requireNumber(value) {
  if (typeof value !== "number") {
    throw new Error("Wert muss eine Zahl sein");
  }
  return value;
}

try {
  requireNumber("42");
} catch (error) {
  console.error(error.name, error.message);
}

Der Error enthält wichtige Infos: name, message und häufig einen stack, der dir die Fehlerstelle zeigt.

Eigene Error-Klassen für klare Logik

Mit eigenen Error-Klassen kannst du Fehler gezielter unterscheiden (z. B. Validierung vs. Netzwerk).

class ValidationError extends Error {
  constructor(message, field) {
    super(message);
    this.name = "ValidationError";
    this.field = field;
  }
}

function validateEmail(email) {
  if (!email.includes("@")) {
    throw new ValidationError("E-Mail ist ungültig", "email");
  }
}

try {
  validateEmail("max.example.com");
} catch (error) {
  if (error instanceof ValidationError) {
    console.error(`Feld ${error.field}: ${error.message}`);
  } else {
    throw error;
  }
}

Asynchrone Fehler: Promises und async/await

Bei asynchronem Code reicht ein normales try/catch nicht aus. Du brauchst entweder .catch() oder ein try/catch in einer async-Funktion.

async function loadUser(id) {
  try {
    const response = await fetch(`/api/users/${id}`);
    if (!response.ok) {
      throw new Error("Serverantwort war nicht ok");
    }
    return await response.json();
  } catch (error) {
    console.error("Fehler beim Laden:", error.message);
    return null;
  }
}

Fehler nicht verschlucken

Manchmal willst du einen Fehler kurz loggen, aber danach weiterreichen. Dann wirfst du ihn erneut:

try {
  riskyOperation();
} catch (error) {
  console.error("Fehler in riskyOperation:", error.message);
  throw error; // Weiterreichen an die nächsthöhere Ebene
}

So bleibt der Fehler sichtbar, aber du behältst trotzdem die Kontrolle über den Ablauf.

Praxis-Tipp: Debugging gezielt einsetzen

Error Handling ist die Basis, Debugging ist die Lupe. Wenn du wissen willst, wie du Bugs systematisch findest, lies den passenden Blog-Post: Debugging wie ein Profi.

Mini-Quiz

  1. Wann wird der finally-Block ausgeführt?
  2. Was ist der Unterschied zwischen throw und return?
  3. Warum braucht asynchroner Code ein eigenes try/catch?

Antworten (kurz):

  1. Immer, egal ob ein Fehler auftritt.
  2. throw unterbricht den normalen Ablauf mit einem Fehler, return beendet die Funktion regulär.
  3. Weil Fehler in Promises außerhalb des ursprünglichen Call-Stacks passieren.

Zusammenfassung

Du hast gelernt, wie du Fehler mit try/catch/finally abfängst, gezielt eigene Fehler wirfst und asynchronen Code sicher behandelst. Mit sauberem Error Handling wird dein Code robuster, leichter zu debuggen und deutlich nutzerfreundlicher.


Weiterführende Links: