From 911d2d22de2fda78c103fc2a0d552c88b78d3aba Mon Sep 17 00:00:00 2001 From: Felix Becker Date: Sat, 25 Apr 2020 15:23:34 +0200 Subject: [PATCH 1/2] Add failing test for throwing scalars --- tests/same_window.comlink.test.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/same_window.comlink.test.js b/tests/same_window.comlink.test.js index 7bfb9aa7..e64838f2 100644 --- a/tests/same_window.comlink.test.js +++ b/tests/same_window.comlink.test.js @@ -147,6 +147,21 @@ describe("Comlink in the same realm", function() { } }); + it("can rethrow scalars", async function() { + const thing = Comlink.wrap(this.port1); + Comlink.expose(_ => { + throw "oops"; + }, this.port2); + try { + await thing(); + throw "Should have thrown"; + } catch (err) { + expect(err).to.not.eq("Should have thrown"); + expect(err).to.be("oops"); + expect(typeof err).to.be("string"); + } + }); + it("can work with parameterized functions", async function() { const thing = Comlink.wrap(this.port1); Comlink.expose((a, b) => a + b, this.port2); From a88f6002985720de265a4b9869e69c88f53fec20 Mon Sep 17 00:00:00 2001 From: Surma Date: Mon, 27 Apr 2020 17:01:45 +0100 Subject: [PATCH 2/2] Switch to throw marker to allow throwing scalars --- src/comlink.ts | 35 ++++++++++++++----------------- tests/same_window.comlink.test.js | 8 +++---- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/comlink.ts b/src/comlink.ts index b734ff5e..3cc4e90d 100644 --- a/src/comlink.ts +++ b/src/comlink.ts @@ -25,7 +25,7 @@ export { Endpoint }; export const proxyMarker = Symbol("Comlink.proxy"); export const createEndpoint = Symbol("Comlink.endpoint"); export const releaseProxy = Symbol("Comlink.releaseProxy"); -const throwSet = new WeakSet(); +const throwMarker = Symbol("Comlink.thrown"); // prettier-ignore type Promisify = @@ -100,24 +100,23 @@ export const transferHandlers = new Map([ [ "throw", { - canHandle: obj => throwSet.has(obj), - serialize(obj) { - const isError = obj instanceof Error; - let serialized = obj; + canHandle: obj => typeof obj === "object" && throwMarker in obj, + serialize({ value }) { + const isError = value instanceof Error; + let serialized = { isError, value }; if (isError) { - serialized = { - isError, - message: obj.message, - stack: obj.stack + serialized.value = { + message: value.message, + stack: value.stack }; } return [serialized, []]; }, - deserialize(obj) { - if ((obj as any).isError) { - throw Object.assign(new Error(), obj); + deserialize(serialized) { + if (serialized.isError) { + throw Object.assign(new Error(), serialized.value); } - throw obj; + throw serialized.value; } } ] @@ -173,14 +172,12 @@ export function expose(obj: any, ep: Endpoint = self as any) { } break; } - } catch (e) { - returnValue = e; - throwSet.add(e); + } catch (value) { + returnValue = { value, [throwMarker]: 0 }; } Promise.resolve(returnValue) - .catch(e => { - throwSet.add(e); - return e; + .catch(value => { + return { value, [throwMarker]: 0 }; }) .then(returnValue => { const [wireValue, transferables] = toWireValue(returnValue); diff --git a/tests/same_window.comlink.test.js b/tests/same_window.comlink.test.js index e64838f2..be93cc3a 100644 --- a/tests/same_window.comlink.test.js +++ b/tests/same_window.comlink.test.js @@ -142,7 +142,7 @@ describe("Comlink in the same realm", function() { await thing(); throw "Should have thrown"; } catch (err) { - expect(err).to.not.eq("Should have thrown"); + expect(err).to.not.equal("Should have thrown"); expect(err.test).to.equal(true); } }); @@ -156,9 +156,9 @@ describe("Comlink in the same realm", function() { await thing(); throw "Should have thrown"; } catch (err) { - expect(err).to.not.eq("Should have thrown"); - expect(err).to.be("oops"); - expect(typeof err).to.be("string"); + expect(err).to.not.equal("Should have thrown"); + expect(err).to.equal("oops"); + expect(typeof err).to.equal("string"); } });