Signatur
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
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());
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);
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);
// 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/catchumawait. - 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“. reasonist nicht zwingend einError: Auch Strings,undefinedoder Objekte sind möglich; beim Zugriff auf.message/.stackoptional 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.