Start · Sprachen · JavaScript · Referenz · MessagePort: messageerror

MessagePort: messageerror

Ereignis

Wird an einem <code>MessagePort</code> ausgelöst, wenn eine empfangene Nachricht nicht deserialisiert werden kann.

seit JavaScript Baseline: alle modernen Browser (Chrome 60+, Firef Kategorie: webapi

Signatur

port.addEventListener("messageerror", handler)

Beschreibung

Das Ereignis messageerror wird an einem MessagePort ausgelöst, wenn eine über den Kanal eingetroffene Nachricht auf der Empfängerseite nicht deserialisiert werden kann. Der Absender hat die Daten zwar erfolgreich mit dem Structured-Clone-Algorithmus serialisiert, das Wiederherstellen im Zielkontext scheitert jedoch. Statt message wird dann messageerror ausgelöst.

Typische Ursachen sind zum Beispiel ein SharedArrayBuffer, der in einen Kontext ohne Cross-Origin-Isolation (fehlende COOP/COEP-Header) oder in einen anderen Agent-Cluster gesendet wird, oder ein WebAssembly.Module, das an einen Kontext geschickt wird, der es nicht annehmen darf. Ist ein Objekt dagegen grundsätzlich nicht klonbar (etwa Funktionen oder DOM-Knoten), wirft schon postMessage() beim Absender eine DataCloneError-Ausnahme, und es wird kein messageerror ausgelöst.

Registrieren kannst du den Handler per port.addEventListener("messageerror", handler) oder über die Eigenschaft port.onmessageerror = handler. Das Ereignisobjekt ist ein MessageEvent, das nicht abgebrochen werden kann und nicht aufsteigt. Seine Eigenschaft data ist dabei null, weil sich die Nutzdaten ja nicht wiederherstellen ließen.

Wichtig: Bei addEventListener musst du den Port explizit mit port.start() öffnen, damit Nachrichten zugestellt werden. Wenn du onmessage setzt, geschieht das automatisch; onmessageerror allein startet den Port dagegen nicht.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "messageerror".
$handler Pflicht (event: MessageEvent) => void Callback, das ein MessageEvent erhält. event.data ist null, event.target ist der betroffene MessagePort.
$options boolean | AddEventListenerOptions false Optionen wie once oder signal (AbortSignal zum Entfernen des Listeners).

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Der Handler erhält ein MessageEvent mit data === null.

Beispiele

messageerror per addEventListener überwachen

const { port1, port2 } = new MessageChannel();

port1.addEventListener('message', (event) => {
  console.log('Empfangen:', event.data);
});

port1.addEventListener('messageerror', (event) => {
  console.error('Nachricht nicht deserialisierbar, data =', event.data);
});

// Bei addEventListener muss der Port explizit gestartet werden
port1.start();

port2.postMessage({ status: 'ok' });
Empfangen: { status: 'ok' }

Handler über onmessageerror setzen und wieder entfernen

const channel = new MessageChannel();
const port = channel.port1;

port.onmessage = (event) => console.log('Daten:', event.data);
port.onmessageerror = (event) => {
  console.warn('Deserialisierung fehlgeschlagen an Port', event.target);
};

// Später: Handler entfernen
port.onmessageerror = null;

Worker-Kommunikation mit Fehlerprotokoll und AbortSignal

// main.js
const worker = new Worker('worker.js');
const { port1, port2 } = new MessageChannel();
const controller = new AbortController();

port1.addEventListener('message', (e) => console.log('Worker sagt:', e.data), {
  signal: controller.signal
});

port1.addEventListener('messageerror', () => {
  // z. B. SharedArrayBuffer ohne Cross-Origin-Isolation
  console.error('Worker-Nachricht konnte nicht gelesen werden');
  controller.abort(); // beide Listener entfernen
  port1.close();
}, { signal: controller.signal });

port1.start();
worker.postMessage({ port: port2 }, [port2]);

// worker.js
// self.onmessage = ({ data }) => data.port.postMessage('Hallo vom Worker');
Worker sagt: Hallo vom Worker

// Wichtig · Fallstricke

  • Nicht mit DataCloneError verwechseln: Nicht klonbare Werte (Funktionen, DOM-Knoten, Symbole) lösen schon beim Absender in postMessage() eine Ausnahme aus. messageerror betrifft nur Fehler beim Deserialisieren auf der Empfängerseite.
  • port.start() nicht vergessen: Ohne start() (oder das Setzen von onmessage) werden keine Ereignisse zugestellt, auch kein messageerror.
  • event.data ist immer null. Die ursprünglichen Daten lassen sich nicht wiederherstellen, deshalb braucht es auf Anwendungsebene eine Fehlerbehandlung, z. B. eine erneute Anfrage mit einem anderen Datenformat.
  • Häufigste Ursache in der Praxis ist ein SharedArrayBuffer ohne Cross-Origin-Opener-Policy: same-origin und Cross-Origin-Embedder-Policy: require-corp. Prüfe das mit self.crossOriginIsolated.
  • Kompatibilität: In Chromium und Firefox seit Langem verfügbar, in Safari erst ab 16.4. In Node.js gibt es das Ereignis am MessagePort von worker_threads seit Version 14.5/15.