From b2404a62d044703d35a7c9cd2d881f85d55bf528 Mon Sep 17 00:00:00 2001 From: KirtiRamchandani Date: Mon, 25 May 2026 17:52:31 +0530 Subject: [PATCH] fix: include serialization error details --- src/comlink.ts | 14 +++++++++++--- tests/same_window.comlink.test.js | 32 ++++++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/comlink.ts b/src/comlink.ts index 27c13694..82124060 100644 --- a/src/comlink.ts +++ b/src/comlink.ts @@ -380,7 +380,7 @@ export function expose( .catch((error) => { // Send Serialization Error To Caller const [wireValue, transferables] = toWireValue({ - value: new TypeError("Unserializable return value"), + value: new TypeError(getUnserializableErrorMessage(error)), [throwMarker]: 0, }); ep.postMessage({ ...wireValue, id }, transferables); @@ -399,8 +399,16 @@ function closeEndPoint(endpoint: Endpoint) { if (isMessagePort(endpoint)) endpoint.close(); } +function getUnserializableErrorMessage(error: unknown) { + const details = error instanceof Error ? error.message : String(error); + + return details + ? `Unserializable return value: ${details}` + : "Unserializable return value"; +} + export function wrap(ep: Endpoint, target?: any): Remote { - const pendingListeners : PendingListenersMap = new Map(); + const pendingListeners: PendingListenersMap = new Map(); ep.addEventListener("message", function handleMessage(ev: Event) { const { data } = ev as MessageEvent; @@ -643,7 +651,7 @@ function requestResponseMessage( ep.start(); } ep.postMessage({ id, ...msg }, transfers); -}); + }); } function generateUUID(): string { diff --git a/tests/same_window.comlink.test.js b/tests/same_window.comlink.test.js index 9fea1292..da3f4619 100644 --- a/tests/same_window.comlink.test.js +++ b/tests/same_window.comlink.test.js @@ -645,7 +645,37 @@ describe("Comlink in the same realm", function () { try { await thing.value; } catch (err) { - expect(err.message).to.equal("Unserializable return value"); + expect(err.message).to.contain("Unserializable return value"); + } + }); + + it("includes serialization error details for unserializable return values", async function () { + const transferHandlerName = "throwing-test"; + Comlink.transferHandlers.set(transferHandlerName, { + canHandle(value) { + return value && value.throwOnSerialize === true; + }, + serialize() { + throw new Error("custom serialization failed"); + }, + deserialize() {}, + }); + + try { + const thing = Comlink.wrap(this.port1, { value: {} }); + Comlink.expose({ value: { throwOnSerialize: true } }, this.port2); + + try { + await thing.value; + throw "Should have thrown"; + } catch (err) { + expect(err).to.not.equal("Should have thrown"); + expect(err.message).to.equal( + "Unserializable return value: custom serialization failed" + ); + } + } finally { + Comlink.transferHandlers.delete(transferHandlerName); } }); });