Start · Sprachen · JavaScript · Referenz · EventSource: error

EventSource: error

Ereignis

Wird ausgelöst, wenn eine <code>EventSource</code>-Verbindung nicht geöffnet werden kann oder abbricht. Der Browser versucht danach je nach Fall automatisch, die Verbindung neu aufzubauen.

seit JavaScript Baseline: alle modernen Browser (seit 2020 inkl. E Kategorie: webapi

Signatur

eventSource.addEventListener("error", handler)

Beschreibung

Das error-Ereignis einer EventSource (Server-Sent Events) tritt ein, wenn der Aufbau der Verbindung zum Server fehlschlägt oder eine bestehende Verbindung abbricht. Du registrierst den Handler entweder mit eventSource.addEventListener("error", handler) oder über die Eigenschaft eventSource.onerror = handler.

Das Ereignis ist ein einfaches Event ohne Fehlerdetails. Es enthält keine Fehlermeldung, keinen HTTP-Statuscode und keinen Grund. Um zu erkennen, was passiert ist, prüfst du im Handler eventSource.readyState:

  • EventSource.CONNECTING (0): Die Verbindung ist abgebrochen, zum Beispiel durch einen Netzwerkfehler oder weil der Server die Antwort beendet hat. Der Browser versucht gleich einen automatischen Neuaufbau. Wie lange er wartet, legt der Server mit dem Feld retry: fest.
  • EventSource.CLOSED (2): Die Verbindung ist endgültig gescheitert, zum Beispiel wegen eines HTTP-Status außer 200, eines falschen Content-Type (nicht text/event-stream) oder eines CORS-Fehlers. Der Browser versucht es nicht erneut.

Typische Aufgaben im Handler: den Verbindungsstatus in der Oberfläche anzeigen, Fehler protokollieren, bei CLOSED einen eigenen Neuaufbau mit exponentiellem Backoff starten oder mit close() die Neuversuche des Browsers bewusst stoppen.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignistyp, hier immer "error".
$handler Pflicht (event: Event) => void Callback, der ein einfaches Event erhält. event.target ist die betroffene EventSource.
$options boolean | AddEventListenerOptions false Optionen wie bei addEventListener, z. B. { once: true } oder { signal }.

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Das übergebene Ereignis ist vom Typ Event und nicht abbrechbar (cancelable: false).

Beispiele

Fehler mit addEventListener unterscheiden

const source = new EventSource('/api/stream');

source.addEventListener('error', (event) => {
  const es = event.target;
  if (es.readyState === EventSource.CONNECTING) {
    console.warn('Verbindung unterbrochen – Browser versucht Neuaufbau …');
  } else if (es.readyState === EventSource.CLOSED) {
    console.error('Verbindung endgültig geschlossen.');
  }
});
Verbindung unterbrochen – Browser versucht Neuaufbau …

onerror-Property mit Statusanzeige

const status = document.querySelector('#status');
const source = new EventSource('/notifications');

source.onopen = () => {
  status.textContent = 'Verbunden';
};

source.onerror = () => {
  status.textContent = source.readyState === EventSource.CLOSED
    ? 'Getrennt'
    : 'Verbinde neu …';
};

// Handler später wieder entfernen:
// source.onerror = null;

Eigener Neuaufbau mit exponentiellem Backoff

let delay = 1000;
const MAX_DELAY = 30000;

const connect = () => {
  const source = new EventSource('/api/live');

  source.addEventListener('open', () => {
    delay = 1000; // nach Erfolg zurücksetzen
  });

  source.addEventListener('message', (e) => {
    console.log('Daten:', e.data);
  });

  const onError = () => {
    if (source.readyState === EventSource.CLOSED) {
      source.removeEventListener('error', onError);
      console.log(`Neuer Versuch in ${delay} ms`);
      setTimeout(connect, delay);
      delay = Math.min(delay * 2, MAX_DELAY);
    }
  };

  source.addEventListener('error', onError);
};

connect();
Neuer Versuch in 1000 ms

Browser-Neuversuche bewusst stoppen

const source = new EventSource('/api/stream');
let failures = 0;

source.addEventListener('error', () => {
  failures += 1;
  if (failures >= 3) {
    source.close(); // readyState wird CLOSED, keine weiteren Versuche
    console.error('Stream nach 3 Fehlern aufgegeben.');
  }
});
Stream nach 3 Fehlern aufgegeben.

// Wichtig · Fallstricke

  • Keine Fehlerdetails: Das Ereignis enthält weder Statuscode noch Meldung. Den Grund erfährst du nur über readyState, die Netzwerkanalyse der DevTools oder serverseitiges Logging.
  • Endlose Neuversuche: Solange readyState auf CONNECTING steht, verbindet sich der Browser immer wieder neu, auch wenn der Server dauerhaft nicht erreichbar ist. Mit close() setzt du selbst eine Grenze.
  • Normales Stream-Ende löst ebenfalls error aus: Beendet der Server die Antwort regulär, feuert das Ereignis und ein Neuaufbau folgt. Um den Stream bewusst zu beenden, antwortet der Server mit HTTP 204 No Content. Das führt zu CLOSED.
  • CORS: Für Cross-Origin-Streams braucht der Server passende Access-Control-Allow-Origin-Header. Sollen Cookies mitgeschickt werden, verwendest du new EventSource(url, { withCredentials: true }). CORS-Fehler zeigen sich nur als error mit CLOSED.
  • Verbindungslimit: Über HTTP/1.1 erlauben Browser nur etwa 6 Verbindungen pro Domain, und das über alle Tabs hinweg. Zu viele offene Streams können dazu führen, dass neue hängen bleiben. HTTP/2 löst das Problem.
  • Kompatibilität: Alle modernen Browser unterstützen EventSource. Der Internet Explorer und das alte Edge (vor Chromium) kennen es nicht. In Node.js ist EventSource erst in neueren Versionen (ab 22, zunächst experimentell) global verfügbar.
  • Das Ereignis hat nichts mit einem Ereignis zu tun, das der Server selbst event: error nennt. Solche benutzerdefinierten Ereignisse kommen als MessageEvent an und landen ebenfalls im error-Listener. Wähle serverseitig daher lieber einen anderen Namen.