From 046d847c1b7ba9fcc8e0f3be6e4ff13dac016479 Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Fri, 4 Sep 2026 16:24:08 +0200 Subject: fix(client): a failed spawn() of the node no longer crashes the app spawnNodeDetached() and the Linux dev-mode fallback in node:start called spawn() with no 'error' listener. A spawn failure -- bad path, a stale PATH entry, antivirus interference -- is delivered on that event asynchronously; with nothing listening, Node rethrows it as an uncaught exception and takes the whole Electron main process down with it, instead of the caller's own waitForNode() timeout turning "never came up" into a clean message. Hit directly: ENOENT spawning a stale dev-venv meshbay-node.exe (not the installed one -- where.exe correctly resolves to the bundled exe now). Whatever the trigger, a daemon that fails to start must never be able to take the renderer down with it. Co-Authored-By: Claude Sonnet 5 --- packages/meshbay-client/src/main.js | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'packages/meshbay-client/src') diff --git a/packages/meshbay-client/src/main.js b/packages/meshbay-client/src/main.js index a348007..6c92531 100644 --- a/packages/meshbay-client/src/main.js +++ b/packages/meshbay-client/src/main.js @@ -854,6 +854,13 @@ function registerBridge() { const bin = await findNodeBinary(); if (!bin) throw new Error('meshbay-node not found on PATH'); const child = spawn(bin, [], { detached: true, stdio: 'ignore', windowsHide: true }); + // spawn() failures (bad path, a stale PATH entry, antivirus interference) + // land on the ChildProcess as an 'error' event, asynchronously -- with no + // listener, Node rethrows it as an uncaught exception and takes the whole + // main process down with it. The caller's waitForNode() timeout already + // turns "never came up" into a clean message; this only has to keep that + // path reachable instead of crashing first. + child.on('error', (err) => console.error('[node] failed to start:', err.message)); child.unref(); } @@ -1133,6 +1140,10 @@ function registerBridge() { detached: true, stdio: 'ignore', }); + // Same reason as spawnNodeDetached(): an unhandled 'error' event here + // would crash the whole main process instead of letting the polling + // loop below report "never came up". + child.on('error', (err) => console.error('[node] failed to start:', err.message)); child.unref(); } -- cgit v1.2.3