Start · Sprachen · JavaScript · Referenz · PromiseRejectionEvent

PromiseRejectionEvent

Schnittstelle

Ereignis, das an den globalen Kontext (<code>window</code> oder Worker) gesendet wird, wenn ein Promise abgelehnt wird und kein Ablehnungs-Handler vorhanden ist bzw. später einer hinzukommt.

seit JavaScript Baseline: alle modernen Browser (seit 2021), Web W Kategorie: webapi

Signatur

interface PromiseRejectionEvent extends Event

Beschreibung

PromiseRejectionEvent ist der Ereignistyp für die beiden globalen Ereignisse unhandledrejection und rejectionhandled. Der Browser sendet unhandledrejection, wenn ein Promise abgelehnt wurde und bis zum Ende der aktuellen Mikrotask-Verarbeitung kein .catch()- oder then(…, onRejected)-Handler vorhanden ist. Wird später doch noch ein Handler angehängt, folgt rejectionhandled.

Das Ereignis hat zwei eigene, schreibgeschützte Eigenschaften:

  • promise – das betroffene Promise-Objekt.
  • reason – der Ablehnungsgrund, also der an reject() übergebene Wert bzw. der geworfene Fehler.

Typischer Einsatzzweck ist globales Fehler-Logging und Monitoring: Unbehandelte Ablehnungen, die sonst nur als Konsolenwarnung erscheinen, lassen sich so zentral erfassen und an einen Server melden. Mit event.preventDefault() unterdrückt man die Standardausgabe des Browsers in der Konsole.

Ereignisse werden auf window (bzw. self im Worker) ausgelöst, entweder per addEventListener() oder über die Eigenschaften onunhandledrejection und onrejectionhandled. Ein eigener Konstruktor new PromiseRejectionEvent(type, options) existiert, wird aber vor allem für Tests benötigt.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Konstruktor-Parameter: Ereignisname, in der Regel "unhandledrejection" oder "rejectionhandled".
$options Pflicht object Konstruktor-Optionen: promise (Pflicht, das betroffene Promise), reason (optional, Ablehnungsgrund) sowie die üblichen Event-Optionen bubbles, cancelable, composed.

Rückgabewert

Typ
PromiseRejectionEvent
Beschreibung
Der Konstruktor liefert ein neues Ereignisobjekt mit den schreibgeschützten Eigenschaften promise und reason.

Beispiele

Unbehandelte Ablehnungen global protokollieren

window.addEventListener('unhandledrejection', (event) => {
  console.warn('Unbehandelte Ablehnung:', event.reason);
  // Standard-Konsolenmeldung des Browsers unterdrücken
  event.preventDefault();
});

// Kein .catch() – löst das Ereignis aus
fetch('/gibt-es-nicht.json').then((res) => {
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
});
Unbehandelte Ablehnung: Error: HTTP 404

Fehler an ein Monitoring-Backend senden

const meldeFehler = (event) => {
  const { reason } = event;
  const daten = {
    typ: 'unhandledrejection',
    nachricht: reason instanceof Error ? reason.message : String(reason),
    stack: reason?.stack ?? null,
    url: location.href
  };
  navigator.sendBeacon('/api/fehler', JSON.stringify(daten));
};

window.onunhandledrejection = meldeFehler;

Promise.reject(new TypeError('Konfiguration fehlt'));

Nachträglich behandelte Ablehnungen erkennen

const offen = new Set();

window.addEventListener('unhandledrejection', (e) => {
  offen.add(e.promise);
  console.log('Offen:', offen.size);
});

window.addEventListener('rejectionhandled', (e) => {
  offen.delete(e.promise);
  console.log('Nachträglich behandelt, offen:', offen.size);
});

const p = Promise.reject(new Error('später gefangen'));
setTimeout(() => p.catch(() => {}), 1000);
Offen: 1 Nachträglich behandelt, offen: 0

Ereignis manuell erzeugen (z. B. für Tests)

const promise = Promise.reject(new Error('Test'));
promise.catch(() => {}); // echte Meldung verhindern

const event = new PromiseRejectionEvent('unhandledrejection', {
  promise,
  reason: new Error('Test'),
  cancelable: true
});

window.addEventListener('unhandledrejection', (e) => {
  console.log('Empfangen:', e.reason.message);
}, { once: true });

window.dispatchEvent(event);
Empfangen: Test

// Wichtig · Fallstricke

  • Kein Ersatz für lokale Fehlerbehandlung: Das globale Ereignis ist ein Sicherheitsnetz für Logging. Fehler sollten trotzdem dort mit try/catch bzw. .catch() behandelt werden, wo sie entstehen.
  • Zeitpunkt: unhandledrejection wird erst ausgelöst, wenn die Mikrotask-Warteschlange abgearbeitet ist. Hängt man den Handler in einem späteren Task an (z. B. in setTimeout), gibt es zuerst unhandledrejection und danach rejectionhandled.
  • reason kann alles sein: Nicht jeder Ablehnungsgrund ist ein Error. Vor dem Zugriff auf message oder stack den Typ prüfen.
  • Cross-Origin-Skripte: Bei Ablehnungen aus Skripten anderer Herkunft ohne passende CORS-Freigabe (crossorigin-Attribut) liefern Browser unter Umständen keine Details.
  • Node.js: Dort heißt das Gegenstück process.on('unhandledRejection', (reason, promise) => …). Seit Node.js 15 beenden unbehandelte Ablehnungen standardmäßig den Prozess. Neuere Node-Versionen stellen zusätzlich globale Ereignisse bereit, Browser-Code sollte sich darauf aber nicht verlassen.
  • Kompatibilität: Chrome 49+, Edge 79+, Safari 11+, Firefox 69+. Sehr alte Browser lösen das Ereignis nicht aus.