Signatur
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
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' });
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');
// Wichtig · Fallstricke
- Nicht mit
DataCloneErrorverwechseln: Nicht klonbare Werte (Funktionen, DOM-Knoten, Symbole) lösen schon beim Absender inpostMessage()eine Ausnahme aus.messageerrorbetrifft nur Fehler beim Deserialisieren auf der Empfängerseite. port.start()nicht vergessen: Ohnestart()(oder das Setzen vononmessage) werden keine Ereignisse zugestellt, auch keinmessageerror.event.dataist immernull. 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
SharedArrayBufferohneCross-Origin-Opener-Policy: same-originundCross-Origin-Embedder-Policy: require-corp. Prüfe das mitself.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
MessagePortvonworker_threadsseit Version 14.5/15.