fix(terminal): add try/catch around PTY spawn to prevent silent hangs

Without error handling, if node-pty require or pty.spawn throws (bad
permissions, missing cwd, stale server), the client gets no response and
the terminal hangs with a blinking cursor. Now sends an exit event back.
This commit is contained in:
kumarabhirup 2026-03-08 21:45:17 -07:00
parent 7975405da9
commit 1af9d75396
No known key found for this signature in database
GPG Key ID: DB7CA2289CAB0167
2 changed files with 27 additions and 14 deletions

View File

@ -192,7 +192,6 @@ function TerminalViewport({
} catch {
return;
}
if (msg.type === "output" && msg.data) {
terminal.write(msg.data);
} else if (msg.type === "exit") {

View File

@ -54,21 +54,35 @@ function shellArgs(shell: string): string[] {
function spawnTerminal(ws: WebSocket, cols: number, rows: number, cwd?: string) {
ensureSpawnHelperExecutable();
// eslint-disable-next-line @typescript-eslint/no-require-imports
const nodePty = require("node-pty") as typeof import("node-pty");
let nodePty: typeof import("node-pty");
try {
// eslint-disable-next-line @typescript-eslint/no-require-imports
nodePty = require("node-pty") as typeof import("node-pty");
} catch {
ws.send(JSON.stringify({ type: "exit", exitCode: 1, signal: null }));
return;
}
const shell = defaultShell();
const pty = nodePty.spawn(shell, shellArgs(shell), {
name: "xterm-256color",
cols,
rows,
cwd: cwd || process.env.HOME || process.cwd(),
env: Object.fromEntries(
Object.entries(process.env).filter(
([, v]) => v !== undefined,
),
) as Record<string, string>,
});
const spawnCwd = cwd || process.env.HOME || process.cwd();
let pty: import("node-pty").IPty;
try {
pty = nodePty.spawn(shell, shellArgs(shell), {
name: "xterm-256color",
cols,
rows,
cwd: spawnCwd,
env: Object.fromEntries(
Object.entries(process.env).filter(
([, v]) => v !== undefined,
),
) as Record<string, string>,
});
} catch {
ws.send(JSON.stringify({ type: "exit", exitCode: 1, signal: null }));
return;
}
const session: TerminalSession = { pty, ws };
sessions.set(ws, session);