summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-04 16:24:08 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-04 16:24:08 +0200
commit046d847c1b7ba9fcc8e0f3be6e4ff13dac016479 (patch)
tree15abc20457e68d662ae2a5918916d89859ebce04
parenta4aabd1d33770d6199a8cb7bc87f639668617bc9 (diff)
downloadmeshbay-046d847c1b7ba9fcc8e0f3be6e4ff13dac016479.tar.gz
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 <noreply@anthropic.com>
-rw-r--r--packages/meshbay-client/src/main.js11
1 files changed, 11 insertions, 0 deletions
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();
}