authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-06-20 10:58:03-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-06-20 10:58:03-07:00
log7a8bab5d9df80e06782033d1ee252400e6f048b1
tree690bd0ad8e833919c6a9e414e9f18fa278dd1bad
parent06752526b3354a560d647251676eb9d5c8a50e82
signature Signed by PGP key B5690EEEBB952194

[codex] Keep PTY spawn errors structural (#3325)

Co-authored-by: codex <codex@users.noreply.github.com>

2 files changed, 35 insertions(+), 3 deletions(-)

apps/server/src/terminal/PtyAdapter.test.ts created+34
...@@ -0,0 +1,34 @@
1import { assert, describe, it } from "@effect/vitest";
2import * as Schema from "effect/Schema";
3
4import * as PtyAdapter from "./PtyAdapter.ts";
5
6const isPtySpawnError = Schema.is(PtyAdapter.PtySpawnError);
7
8describe("PtySpawnError", () => {
9 it("derives messages from structural context while preserving the full cause chain", () => {
10 const spawnCause = new Error("spawn /bin/zsh ENOENT");
11 const adapterError = new PtyAdapter.PtySpawnError({
12 adapter: "node-pty",
13 shell: "/bin/zsh",
14 cause: spawnCause,
15 });
16 const managerError = new PtyAdapter.PtySpawnError({
17 adapter: "terminal-manager",
18 attemptedShells: ["/bin/zsh -o nopromptsp", "/bin/bash"],
19 cause: adapterError,
20 });
21
22 assert(isPtySpawnError(managerError));
23 assert.strictEqual(
24 managerError.message,
25 "Failed to spawn PTY process with terminal-manager. Tried shells: /bin/zsh -o nopromptsp, /bin/bash.",
26 );
27 assert.strictEqual(
28 adapterError.message,
29 "Failed to spawn PTY process '/bin/zsh' with node-pty.",
30 );
31 assert.strictEqual(managerError.cause, adapterError);
32 assert.strictEqual(adapterError.cause, spawnCause);
33 });
34});
apps/server/src/terminal/PtyAdapter.ts+1-3
...@@ -25,9 +25,7 @@ export class PtySpawnError extends Schema.TaggedErrorClass<PtySpawnError>()("Pty...@@ -25,9 +25,7 @@ export class PtySpawnError extends Schema.TaggedErrorClass<PtySpawnError>()("Pty
25 this.attemptedShells === undefined || this.attemptedShells.length === 025 this.attemptedShells === undefined || this.attemptedShells.length === 0
26 ? ""26 ? ""
27 : ` Tried shells: ${this.attemptedShells.join(", ")}.`;27 : ` Tried shells: ${this.attemptedShells.join(", ")}.`;
28 const causeMessage =28 return `Failed to spawn PTY process${shell} with ${this.adapter}.${attemptedShells}`;
29 this.cause instanceof Error && this.cause.message.length > 0 ? ` ${this.cause.message}` : "";
30 return `Failed to spawn PTY process${shell} with ${this.adapter}.${attemptedShells}${causeMessage}`;
31 }29 }
32}30}
3331