Start · Sprachen · JavaScript · Referenz · Promise.prototype.catch()

Promise.prototype.catch()

Methode

Registriert eine Funktion, die aufgerufen wird, wenn das Promise abgelehnt wird, und gibt ein neues Promise zurück.

seit JavaScript ES2015 Kategorie: method-property

Signatur

Promise.prototype.catch(onRejected)

Beschreibung

catch() registriert eine Fehlerbehandlung für ein Promise. Die Callback-Funktion läuft, sobald das Promise abgelehnt wird (rejected). Intern entspricht promise.catch(onRejected) dem Aufruf promise.then(undefined, onRejected). Es wird also wirklich then auf dem Objekt aufgerufen.

Die Methode gibt immer ein neues Promise zurück. Deshalb kann man sie verketten: Gibt der Handler einen Wert zurück, wird das neue Promise mit diesem Wert erfüllt, und die Kette läuft danach „normal“ weiter. Wirft der Handler selbst einen Fehler oder gibt er ein abgelehntes Promise zurück, wird das neue Promise ebenfalls abgelehnt.

Ein catch() am Ende einer then-Kette fängt Fehler aus allen vorherigen Schritten ab, egal ob die Ablehnung vom ursprünglichen Promise kommt oder von einer Ausnahme in einem then-Handler. Wenn es kein catch() gibt, lösen abgelehnte Promises das Ereignis unhandledrejection aus (Browser) bzw. beenden in Node.js ab Version 15 standardmäßig den Prozess.

Mit async/await übernimmt meist try...catch diese Aufgabe. catch() bleibt aber nützlich für kurze Fallback-Werte direkt am Ausdruck, zum Beispiel await fetchData().catch(() => null).

Parameter

Name Typ Default Beschreibung
$onRejected (reason: any) => any | undefined Funktion, die mit dem Ablehnungsgrund (reason) aufgerufen wird. Ihr Rückgabewert erfüllt das zurückgegebene Promise. Ist das Argument keine Funktion, wird intern ein Handler verwendet, der den Fehler einfach weiterwirft.

Rückgabewert

Typ
Promise<any>
Beschreibung
Ein neues Promise, das sofort im Zustand pending zurückgegeben wird. Es wird mit dem Rückgabewert von onRejected erfüllt oder abgelehnt, wenn der Handler einen Fehler wirft. Wird das ursprüngliche Promise erfüllt, übernimmt das neue Promise dessen Wert unverändert.

Beispiele

Fetch-Fehler am Ende einer Kette abfangen

fetch('https://api.example.com/users/42')
  .then((res) => {
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    return res.json();
  })
  .then((user) => console.log('Benutzer:', user.name))
  .catch((err) => console.error('Laden fehlgeschlagen:', err.message));
Laden fehlgeschlagen: HTTP 404

Fallback-Wert zurückgeben und Kette fortsetzen

const loadConfig = () => Promise.reject(new Error('Datei fehlt'));

loadConfig()
  .catch(() => ({ theme: 'light', lang: 'de' })) // Standardwerte
  .then((config) => console.log(config.theme));
light

Kombination mit await für optionale Daten

const getAvatar = async (id) => {
  throw new Error(`Kein Avatar für ${id}`);
};

const main = async () => {
  const avatar = await getAvatar(7).catch(() => null);
  console.log(avatar ?? 'Standard-Avatar verwenden');
};

main();
Standard-Avatar verwenden

Fehler protokollieren und weiterwerfen

const saveOrder = () => Promise.reject(new Error('Timeout'));

saveOrder()
  .catch((err) => {
    console.warn('Log:', err.message);
    throw err; // Aufrufer soll den Fehler weiterhin sehen
  })
  .catch((err) => console.error('UI-Meldung:', err.message));
Log: Timeout UI-Meldung: Timeout

// Wichtig · Fallstricke

  • Fehler werden „geschluckt“: Gibt ein catch-Handler nichts zurück, wird das Folge-Promise mit undefined erfüllt. Ein nachfolgendes then läuft dann trotzdem. Soll der Fehler weitergereicht werden, muss man ihn mit throw erneut werfen.
  • Position in der Kette: catch() fängt nur Fehler aus den Schritten davor. Fehler in einem then nach dem catch bleiben unbehandelt.
  • then(ok, fail) ist nicht gleich then(ok).catch(fail): Bei der ersten Variante fängt fail keine Fehler ab, die in ok geworfen werden.
  • Asynchrone Ausnahmen: Fehler, die in einem setTimeout-Callback innerhalb des Executors geworfen werden, lehnen das Promise nicht ab. Deshalb erreicht sie auch catch() nicht. Dort muss man reject() aufrufen.
  • Unbehandelte Ablehnungen: Im Browser wird das Ereignis unhandledrejection ausgelöst. In Node.js (ab Version 15) beendet eine unbehandelte Ablehnung standardmäßig den Prozess.
  • Unterstützt in allen modernen Browsern und in Node.js. Der Internet Explorer unterstützt die Methode nicht, dort ist ein Polyfill nötig. Aufräumarbeiten unabhängig vom Ergebnis gehören besser in finally() (ES2018).