Start · Sprachen · JavaScript · Referenz · Window: unhandledrejection

Window: unhandledrejection

Ereignis

Wird am globalen Objekt ausgelöst, wenn ein Promise abgelehnt wird und bis zum Ende der aktuellen Mikrotask-Verarbeitung kein Ablehnungs-Handler existiert.

seit JavaScript Baseline: alle modernen Browser (seit 2021; Chrome Kategorie: webapi

Signatur

window.addEventListener("unhandledrejection", handler)

Beschreibung

Das Ereignis unhandledrejection wird an das globale Objekt gesendet – im Browser meist window, in Workern der jeweilige WorkerGlobalScope –, sobald ein Promise abgelehnt wird, an dem kein .catch(), kein zweites Argument von .then() und kein umschließendes try/catch um ein await hängt. Das Ereignisobjekt ist ein PromiseRejectionEvent mit den Eigenschaften promise (das betroffene Promise) und reason (der Ablehnungsgrund, meist ein Error).

Gedacht ist das Ereignis als letztes Sicherheitsnetz: für zentrales Fehler-Logging, Telemetrie (z. B. Weiterleitung an einen Fehler-Tracking-Dienst) oder eine generische Fehlermeldung in der Oberfläche. Es ersetzt keine gezielte Fehlerbehandlung an der Stelle, an der ein Promise entsteht.

Das Ereignis ist abbrechbar: Ein Aufruf von event.preventDefault() verhindert die Standardaktion, also die Ausgabe von „Uncaught (in promise)“ in der Entwicklerkonsole. Wird später doch noch ein Handler an das Promise angehängt, feuert zusätzlich das Gegenstück rejectionhandled. Registrieren lässt sich der Handler per addEventListener() oder über die Eigenschaft window.onunhandledrejection.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "unhandledrejection".
$handler Pflicht (event: PromiseRejectionEvent) => void Callback, der ein PromiseRejectionEvent mit event.promise und event.reason erhält.
$options boolean|AddEventListenerOptions false Optionale Listener-Optionen wie once oder signal (zum Entfernen per AbortController).

Rückgabewert

Typ
void
Beschreibung
addEventListener() gibt nichts zurück. Der Handler erhält ein PromiseRejectionEvent; preventDefault() unterdrückt die Standard-Konsolenmeldung.

Beispiele

Zentrales Logging unbehandelter Ablehnungen

window.addEventListener("unhandledrejection", (event) => {
  const { reason } = event;
  console.warn("Unbehandelte Ablehnung:", reason instanceof Error ? reason.message : reason);
});

// Promise ohne .catch()
fetch("https://ungueltige-domain.invalid/api")
  .then((res) => res.json());
Unbehandelte Ablehnung: Failed to fetch

Fehler an einen Tracking-Endpunkt senden und Konsolenmeldung unterdrücken

const reportError = (payload) => {
  navigator.sendBeacon("/api/errors", JSON.stringify(payload));
};

window.onunhandledrejection = (event) => {
  event.preventDefault(); // kein "Uncaught (in promise)" in der Konsole
  const err = event.reason;
  reportError({
    type: "unhandledrejection",
    message: err?.message ?? String(err),
    stack: err?.stack ?? null,
    url: location.href,
    time: new Date().toISOString()
  });
};

const loadUser = async () => {
  throw new Error("Benutzer nicht gefunden");
};

loadUser(); // kein await, kein catch

Listener mit AbortController wieder entfernen

const controller = new AbortController();

const onRejection = (event) => {
  console.log("Abgefangen:", event.reason);
};

window.addEventListener("unhandledrejection", onRejection, {
  signal: controller.signal
});

Promise.reject("Erster Fehler");

// Nach kurzer Zeit wieder abmelden
setTimeout(() => {
  controller.abort(); // alternativ: removeEventListener("unhandledrejection", onRejection)
  Promise.reject("Zweiter Fehler"); // erscheint nur noch in der Konsole
}, 100);
Abgefangen: Erster Fehler

Zusammenspiel mit rejectionhandled

window.addEventListener("unhandledrejection", (e) => {
  console.log("unbehandelt:", e.reason);
});
window.addEventListener("rejectionhandled", (e) => {
  console.log("nachträglich behandelt:", e.reason);
});

const p = Promise.reject("Zeitüberschreitung");

// Handler wird erst später angehängt
setTimeout(() => {
  p.catch(() => {});
}, 500);
unbehandelt: Zeitüberschreitung nachträglich behandelt: Zeitüberschreitung

// Wichtig · Fallstricke

  • Kein Ersatz für lokale Fehlerbehandlung: Der Handler kann das Promise nicht „reparieren“ – der abhängige Code ist bereits gescheitert. Behandeln Sie Fehler weiterhin mit .catch() bzw. try/catch um await.
  • Nicht für synchrone Fehler: Ausnahmen außerhalb von Promises landen im error-Ereignis. Für vollständiges Logging beide Ereignisse abonnieren.
  • Zeitpunkt: Das Ereignis feuert erst, nachdem die Mikrotask-Warteschlange abgearbeitet ist. Wird ein Handler später angehängt, folgt rejectionhandled – Fehler-Tracker sollten dann ggf. „entwarnen“.
  • reason ist nicht zwingend ein Error: Auch Strings, undefined oder Objekte sind möglich; beim Zugriff auf .message/.stack optional chaining nutzen.
  • Cross-Origin-Skripte: Ablehnungen aus Skripten fremder Herkunft ohne CORS (crossorigin-Attribut) werden je nach Browser nicht oder nur eingeschränkt gemeldet.
  • Node.js: Dort heißt das Pendant process.on(\"unhandledRejection\", …) (großes R); seit Node.js 15 beendet eine unbehandelte Ablehnung standardmäßig den Prozess. Deno und neuere Node-Versionen unterstützen zusätzlich das globale Ereignis.
  • Kompatibilität: In allen aktuellen Browsern verfügbar (Firefox erst ab Version 69); auch in Web- und Service-Workern über self.