fix(desktop): show explicit missing Node errors (#336)

Fixes #294

## Summary
- detect missing desktop Node runtimes before spawning the bundled CLI
- return a clear error message that tells users to install Node.js or
set `NODE_BINARY`
- handle both direct spawns and desktop-shell launches consistently

## Validation
- `npm run bundle:server --workspace @codenomad/tauri-app && cargo build
--manifest-path packages/tauri-app/src-tauri/Cargo.toml`
- exercised the missing-runtime path in the Linux VM by launching with
an invalid `NODE_BINARY`
This commit is contained in:
Pascal André
2026-04-19 00:39:39 +02:00
committed by GitHub
parent cb84547c88
commit e28e9f5879

View File

@@ -38,6 +38,7 @@ use windows_sys::Win32::System::JobObjects::{
#[cfg(windows)]
const CREATE_NO_WINDOW: u32 = 0x08000000;
const MISSING_NODE_PREFIX: &str = "CODENOMAD_MISSING_NODE:";
#[cfg(windows)]
#[derive(Debug)]
@@ -630,6 +631,13 @@ impl CliProcessManager {
let use_user_shell = supports_user_shell();
if !use_user_shell && which::which(&resolution.node_binary).is_err() {
return Err(anyhow::anyhow!(
"Node binary '{}' not found. CodeNomad desktop currently requires Node.js installed on the system, or set NODE_BINARY to a valid runtime path.",
resolution.node_binary
));
}
let command_info = if use_user_shell {
log_line("spawning via user shell");
ShellCommandType::UserShell(build_shell_command_string(&resolution, &args)?)
@@ -641,14 +649,6 @@ impl CliProcessManager {
})
};
if !use_user_shell {
if which::which(&resolution.node_binary).is_err() {
return Err(anyhow::anyhow!(
"Node binary not found. Make sure Node.js is installed."
));
}
}
let child = match &command_info {
ShellCommandType::UserShell(cmd) => {
log_line(&format!("spawn command: {} {:?}", cmd.shell, cmd.args));
@@ -920,6 +920,17 @@ impl CliProcessManager {
continue;
}
if let Some(node_binary) = line.strip_prefix(MISSING_NODE_PREFIX) {
let mut locked = status.lock();
if locked.error.is_none() {
locked.error = Some(format!(
"Node binary '{}' not found in the desktop shell environment. CodeNomad desktop currently requires Node.js installed on the system, or set NODE_BINARY to a valid runtime path.",
node_binary.trim()
));
}
continue;
}
if let Some(url) = local_url_regex
.as_ref()
.and_then(|re| re.captures(line).and_then(|c| c.get(1)))
@@ -1248,7 +1259,13 @@ fn build_shell_command_string(
for arg in entry.runner_args(cli_args) {
quoted.push(shell_escape(&arg));
}
let command = format!("ELECTRON_RUN_AS_NODE=1 exec {}", quoted.join(" "));
let command = format!(
"if command -v {} >/dev/null 2>&1; then ELECTRON_RUN_AS_NODE=1 exec {}; else printf '%s%s\\n' '{}' {} >&2; exit 127; fi",
shell_escape(&entry.node_binary),
quoted.join(" "),
MISSING_NODE_PREFIX,
shell_escape(&entry.node_binary),
);
let args = build_shell_args(&shell, &command);
log_line(&format!("user shell command: {} {:?}", shell, args));
Ok(ShellCommand { shell, args })