Signatur
Beschreibung
Das error-Ereignis gehört zum Interface ServiceWorker, das von EventTarget erbt (über den AbstractWorker-Mixin). Es wird auf der Seitenseite ausgelöst, also auf dem ServiceWorker-Objekt, das man z. B. über navigator.serviceWorker.controller oder registration.installing, registration.waiting bzw. registration.active erhält. Es ist nicht abbrechbar und steigt nicht auf (kein Bubbling).
Einen Handler registriert man entweder mit addEventListener("error", handler) oder über die Eigenschaft onerror. Der Handler bekommt ein allgemeines Event-Objekt. Anders als bei window.onerror gibt es darin keine ausführlichen Angaben wie Meldung, Datei oder Zeile, weil diese Informationen aus Sicherheitsgründen nicht über die Grenze zum Worker weitergegeben werden.
In der Praxis dient das Ereignis vor allem der Diagnose und Überwachung: Man kann damit mitbekommen, dass ein bestimmter Worker ein Problem hat, und das zum Beispiel an einen Logging-Dienst melden. Fehler bei der Registrierung selbst (Syntaxfehler im Skript, 404, falscher MIME-Typ, falscher Gültigkeitsbereich) fängt man dagegen zuverlässiger über das abgelehnte Promise von navigator.serviceWorker.register() ab.
Fehler innerhalb des Service Workers lassen sich direkt im Worker-Skript mit self.addEventListener("error", …) und self.addEventListener("unhandledrejection", …) auf dem ServiceWorkerGlobalScope behandeln. Dort erhält man ein ErrorEvent mit message, filename, lineno und error.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname, hier immer "error". |
|
| $handler Pflicht | (event: Event) => void | Callback, der beim Fehler aufgerufen wird. Er bekommt ein allgemeines Event, dessen target das betroffene ServiceWorker-Objekt ist. |
|
| $options | boolean | AddEventListenerOptions | false | Optionale Listener-Optionen wie once, signal oder capture. |
Rückgabewert
addEventListener gibt nichts zurück. Der Handler bekommt ein Event-Objekt vom Typ "error".Beispiele
Fehler des aktiven Service Workers per addEventListener protokollieren
const registerSW = async () => {
if (!('serviceWorker' in navigator)) return;
try {
const registration = await navigator.serviceWorker.register('/sw.js');
const worker = registration.installing ?? registration.waiting ?? registration.active;
worker?.addEventListener('error', (event) => {
console.error('Service-Worker-Fehler:', event.type, event.target.scriptURL);
});
} catch (err) {
// Registrierungsfehler (404, Syntaxfehler, falscher MIME-Typ …)
console.error('Registrierung fehlgeschlagen:', err.message);
}
};
registerSW();
Variante mit der onerror-Eigenschaft am Controller
const controller = navigator.serviceWorker.controller;
if (controller) {
controller.onerror = (event) => {
console.warn(`Fehler im Worker (Status: ${event.target.state})`);
};
}
// Handler später wieder entfernen
// controller.onerror = null;
Listener mit AbortController aufräumen und an Monitoring melden
const ac = new AbortController();
const watchWorker = (worker) => {
worker.addEventListener('error', () => {
navigator.sendBeacon('/api/log', JSON.stringify({
kind: 'sw-error',
script: worker.scriptURL,
state: worker.state,
time: Date.now()
}));
}, { signal: ac.signal });
};
const reg = await navigator.serviceWorker.ready;
if (reg.active) watchWorker(reg.active);
// z. B. beim Verlassen einer SPA-Ansicht:
// ac.abort(); // entfernt den Listener
Ergänzend: Fehler direkt im Service-Worker-Skript abfangen (sw.js)
// sw.js – läuft im ServiceWorkerGlobalScope
self.addEventListener('error', (event) => {
console.error('SW-intern:', event.message, `${event.filename}:${event.lineno}`);
});
self.addEventListener('unhandledrejection', (event) => {
console.error('Unbehandeltes Promise im SW:', event.reason);
});
// Wichtig · Fallstricke
- Kaum Details: Auf der Seitenseite ist das Ereignis ein einfaches
Event, keinErrorEvent. Meldung, Zeilennummer und Stacktrace fehlen. Ausführliche Fehlerdaten bekommt man nur im Worker selbst (self.onerror). Von dort kann man sie bei Bedarf perpostMessage()an die Clients schicken. - Registrierungsfehler: Scheitert
navigator.serviceWorker.register(), wird das Promise abgelehnt. Daserror-Ereignis ist dafür kein verlässlicher Ersatz, also immertry/catchbzw..catch()verwenden. - Browser-Unterschiede: Wann genau das Ereignis auf dem
ServiceWorker-Objekt ausgelöst wird, setzen die Browser unterschiedlich um. In vielen Fällen erscheinen Laufzeitfehler nur in den Entwicklerwerkzeugen des Workers. Deshalb sollte man sich zum Überwachen nicht allein auf dieses Ereignis verlassen. - Nicht verwechseln:
navigator.serviceWorker(ServiceWorkerContainer) hat ein eigenesmessageerror-Ereignis, aber keinerror-Ereignis für Worker-Fehler. - Service Worker gibt es nur in sicheren Kontexten (HTTPS oder
localhost). In privaten Fenstern mancher Browser (z. B. Firefox) stehen sie nicht zur Verfügung. - Wird der Worker ersetzt (
updatefound,statechange→redundant), muss man die Listener am neuenServiceWorker-Objekt neu registrieren.