Signatur
Beschreibung
Das error-Ereignis tritt am Worker-Objekt auf, also im Haupt-Thread bzw. in dem Kontext, der den Worker mit new Worker() erzeugt hat. Ausgelöst wird es in zwei Fällen:
- Laufzeitfehler im Worker: Im Worker-Skript wird eine Ausnahme geworfen und nicht abgefangen, z. B. ein
TypeErroroder ein mitthrowausgelöster Fehler. Dann ist das Ereignis einErrorEventmitmessage,filename,linenoundcolno. - Ladefehler: Das Skript kann nicht geladen oder geparst werden, z. B. bei HTTP 404, falschem MIME-Typ, Syntaxfehler oder einem fehlgeschlagenen
importin einem Modul-Worker. Je nach Browser kommt dann oft nur ein einfachesEventohne Detailangaben an.
Du kannst das Ereignis mit worker.addEventListener("error", handler) abonnieren oder über die Eigenschaft worker.onerror = handler setzen. Das Ereignis steigt nicht auf (bubbles: false), lässt sich aber abbrechen: Rufst du event.preventDefault() auf, erscheint der Fehler nicht mehr als „Uncaught“-Meldung in der Konsole.
Wichtig ist die Reihenfolge: Ein Laufzeitfehler wird zuerst im Worker am globalen Objekt (self.onerror bzw. self.addEventListener("error", …)) ausgelöst. Nur wenn er dort nicht per preventDefault() behandelt wird, gelangt er als error-Ereignis zum Worker-Objekt im Elternkontext. Nutze das Ereignis, um abgestürzte Worker zu erkennen, Fehler zu protokollieren, den Worker neu zu starten oder auf eine Berechnung im Haupt-Thread auszuweichen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname, hier "error". |
|
| $handler Pflicht | (event: ErrorEvent | Event) => void | Callback, der das Ereignis erhält. Bei Laufzeitfehlern ist es ein ErrorEvent mit message, filename, lineno und colno, bei Ladefehlern oft nur ein Event. |
|
| $options | boolean | AddEventListenerOptions | false | Die üblichen Optionen von addEventListener, z. B. { once: true } oder { signal }. |
Rückgabewert
addEventListener gibt nichts zurück. Setzt du die Eigenschaft onerror, enthält sie den zugewiesenen Handler oder null.Beispiele
Laufzeitfehler im Worker mit addEventListener abfangen
// Worker aus einem Blob erzeugen, damit das Beispiel ohne eigene Datei läuft
const code = `
self.onmessage = (e) => {
if (typeof e.data !== 'number') {
throw new TypeError('Zahl erwartet, erhalten: ' + typeof e.data);
}
self.postMessage(e.data * 2);
};
`;
const url = URL.createObjectURL(new Blob([code], { type: 'text/javascript' }));
const worker = new Worker(url);
worker.addEventListener('error', (event) => {
event.preventDefault(); // keine „Uncaught“-Meldung in der Konsole
console.log('Fehler im Worker:', event.message);
console.log('Zeile:', event.lineno, 'Spalte:', event.colno);
});
worker.addEventListener('message', (e) => console.log('Ergebnis:', e.data));
worker.postMessage(21);
worker.postMessage('abc');
Ladefehler erkennen und auf den Haupt-Thread ausweichen (onerror-Eigenschaft)
const heavyTask = (n) => {
let sum = 0;
for (let i = 0; i < n; i++) sum += i;
return sum;
};
const worker = new Worker('/js/gibt-es-nicht.js');
worker.onerror = (event) => {
// Bei Ladefehlern gibt es meist kein message/lineno
const detail = event instanceof ErrorEvent ? event.message : 'Skript nicht ladbar';
console.warn('Worker nicht verfügbar:', detail);
worker.terminate();
console.log('Fallback-Ergebnis:', heavyTask(1_000_000));
};
Fehler schon im Worker behandeln, damit sie nicht zum Elternkontext gelangen
const code = `
self.addEventListener('error', (event) => {
// Fehler selbst melden und Weiterleitung verhindern
self.postMessage({ type: 'error', message: event.message });
event.preventDefault();
});
setTimeout(() => { undefinedFunction(); }, 0);
`;
const worker = new Worker(URL.createObjectURL(new Blob([code])));
worker.onerror = () => console.log('Wird NICHT ausgelöst');
worker.onmessage = ({ data }) => {
if (data.type === 'error') console.log('Vom Worker gemeldet:', data.message);
};
Worker nach einem Absturz automatisch neu starten
const workerUrl = URL.createObjectURL(new Blob([
`self.onmessage = (e) => { if (e.data === 'crash') throw new Error('Boom'); self.postMessage('ok'); };`
]));
let restarts = 0;
const createWorker = () => {
const w = new Worker(workerUrl);
w.addEventListener('error', (event) => {
event.preventDefault();
console.log(`Absturz (${event.message}), Neustart #${++restarts}`);
w.terminate();
if (restarts < 3) current = createWorker();
}, { once: true });
w.onmessage = (e) => console.log('Antwort:', e.data);
return w;
};
let current = createWorker();
current.postMessage('crash');
setTimeout(() => current.postMessage('hallo'), 100);