Start · Sprachen · JavaScript · Referenz · Worker: error

Worker: error

Ereignis

Wird am <code>Worker</code>-Objekt im erzeugenden Kontext ausgelöst, wenn im Worker ein nicht abgefangener Fehler auftritt oder das Worker-Skript nicht geladen werden kann.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

worker.addEventListener("error", handler)

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 TypeError oder ein mit throw ausgelöster Fehler. Dann ist das Ereignis ein ErrorEvent mit message, filename, lineno und colno.
  • Ladefehler: Das Skript kann nicht geladen oder geparst werden, z. B. bei HTTP 404, falschem MIME-Typ, Syntaxfehler oder einem fehlgeschlagenen import in einem Modul-Worker. Je nach Browser kommt dann oft nur ein einfaches Event ohne 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

Typ
void
Beschreibung
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');
Ergebnis: 42 Fehler im Worker: Uncaught TypeError: Zahl erwartet, erhalten: string Zeile: 4 Spalte: 13

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));
};
Worker nicht verfügbar: Skript nicht ladbar Fallback-Ergebnis: 499999500000

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);
};
Vom Worker gemeldet: Uncaught ReferenceError: undefinedFunction is not defined

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);
Absturz (Uncaught Error: Boom), Neustart #1 Antwort: ok