From 34d6a72bb839abc055f46b8e533e1ee4e39cfd76 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Thu, 22 Jun 2023 15:31:34 +0000 Subject: [PATCH] Don't panic when platformBindings.connect throws an exception (#795) * Don't panic when platformBindings.connect throws an exception * CHANGELOG link * Docfix * Tweak code a bit --- wasm-node/CHANGELOG.md | 4 + wasm-node/javascript/src/internals/client.ts | 84 ++++++++++++-------- 2 files changed, 53 insertions(+), 35 deletions(-) diff --git a/wasm-node/CHANGELOG.md b/wasm-node/CHANGELOG.md index 12c6070968..2a819fb5bd 100644 --- a/wasm-node/CHANGELOG.md +++ b/wasm-node/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Fixed + +- Fix not absorbing the JavaScript exception triggered by the browser when connecting to a `ws://` node when smoldot is embedded in a web page served over `https://`. ([#795](https://github.com/smol-dot/smoldot/pull/795)) + ## 1.0.10 - 2023-06-19 ### Changed diff --git a/wasm-node/javascript/src/internals/client.ts b/wasm-node/javascript/src/internals/client.ts index cf2df48614..28e070e819 100644 --- a/wasm-node/javascript/src/internals/client.ts +++ b/wasm-node/javascript/src/internals/client.ts @@ -27,7 +27,7 @@ export interface PlatformBindings { * Tries to open a new connection using the given configuration. * * @see Connection - * @throws {@link ConnectionError} If the multiaddress couldn't be parsed or contains an invalid protocol. + * @throws {@link Error} */ connect(config: ConnectionConfig): Connection; @@ -331,40 +331,54 @@ export function start(options: ClientOptions, wasmModule: SmoldotBytecode | Prom } case "new-connection": { const connectionId = event.connectionId; - state.connections.set(connectionId, platformBindings.connect({ - address: event.address, - onConnectionReset(message) { - if (state.instance.status !== "ready") - throw new Error(); - state.connections.delete(connectionId); - state.instance.instance.connectionReset(connectionId, message); - }, - onMessage(message, streamId) { - if (state.instance.status !== "ready") - throw new Error(); - state.instance.instance.streamMessage(connectionId, message, streamId); - }, - onStreamOpened(streamId, direction, initialWritableBytes) { - if (state.instance.status !== "ready") - throw new Error(); - state.instance.instance.streamOpened(connectionId, streamId, direction, initialWritableBytes); - }, - onOpen(info) { - if (state.instance.status !== "ready") - throw new Error(); - state.instance.instance.connectionOpened(connectionId, info); - }, - onWritableBytes(numExtra, streamId) { - if (state.instance.status !== "ready") - throw new Error(); - state.instance.instance.streamWritableBytes(connectionId, numExtra, streamId); - }, - onStreamReset(streamId) { - if (state.instance.status !== "ready") - throw new Error(); - state.instance.instance.streamReset(connectionId, streamId); - }, - })); + + let connection; + try { + connection = platformBindings.connect({ + address: event.address, + onConnectionReset(message) { + if (state.instance.status !== "ready") + throw new Error(); + state.connections.delete(connectionId); + state.instance.instance.connectionReset(connectionId, message); + }, + onMessage(message, streamId) { + if (state.instance.status !== "ready") + throw new Error(); + state.instance.instance.streamMessage(connectionId, message, streamId); + }, + onStreamOpened(streamId, direction, initialWritableBytes) { + if (state.instance.status !== "ready") + throw new Error(); + state.instance.instance.streamOpened(connectionId, streamId, direction, initialWritableBytes); + }, + onOpen(info) { + if (state.instance.status !== "ready") + throw new Error(); + state.instance.instance.connectionOpened(connectionId, info); + }, + onWritableBytes(numExtra, streamId) { + if (state.instance.status !== "ready") + throw new Error(); + state.instance.instance.streamWritableBytes(connectionId, numExtra, streamId); + }, + onStreamReset(streamId) { + if (state.instance.status !== "ready") + throw new Error(); + state.instance.instance.streamReset(connectionId, streamId); + }, + }); + + } catch(error) { + const errorMsg = error instanceof Error ? error.toString() : "Uncaught exception while connecting"; + setTimeout(() => { + if (state.instance.status === 'ready') + state.instance.instance.connectionReset(connectionId, errorMsg); + }, 0); + break; + } + + state.connections.set(connectionId, connection); break; } case "connection-reset": {