Signatur
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 Feldretry:fest.EventSource.CLOSED(2): Die Verbindung ist endgültig gescheitert, zum Beispiel wegen eines HTTP-Status außer 200, eines falschenContent-Type(nichttext/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
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.');
}
});
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();
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.');
}
});
// 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
readyStateaufCONNECTINGsteht, verbindet sich der Browser immer wieder neu, auch wenn der Server dauerhaft nicht erreichbar ist. Mitclose()setzt du selbst eine Grenze. - Normales Stream-Ende löst ebenfalls
erroraus: Beendet der Server die Antwort regulär, feuert das Ereignis und ein Neuaufbau folgt. Um den Stream bewusst zu beenden, antwortet der Server mit HTTP204 No Content. Das führt zuCLOSED. - CORS: Für Cross-Origin-Streams braucht der Server passende
Access-Control-Allow-Origin-Header. Sollen Cookies mitgeschickt werden, verwendest dunew EventSource(url, { withCredentials: true }). CORS-Fehler zeigen sich nur alserrormitCLOSED. - 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 istEventSourceerst 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: errornennt. Solche benutzerdefinierten Ereignisse kommen alsMessageEventan und landen ebenfalls imerror-Listener. Wähle serverseitig daher lieber einen anderen Namen.