diff --git a/apps/server/src/terminal/BunPtyAdapter.test.ts b/apps/server/src/terminal/BunPtyAdapter.test.ts new file mode 100644 index 00000000000..39e811db3a9 --- /dev/null +++ b/apps/server/src/terminal/BunPtyAdapter.test.ts @@ -0,0 +1,17 @@ +import { expect, it } from "@effect/vitest"; + +import { BunPtyOperationUnavailableError } from "./BunPtyAdapter.ts"; + +it("describes unavailable Bun PTY operations structurally", () => { + const error = new BunPtyOperationUnavailableError({ + operation: "resize", + pid: 42, + }); + + expect(error).toMatchObject({ + _tag: "BunPtyOperationUnavailableError", + operation: "resize", + pid: 42, + }); + expect(error.message).toBe("Bun PTY resize is unavailable for process 42."); +}); diff --git a/apps/server/src/terminal/BunPtyAdapter.ts b/apps/server/src/terminal/BunPtyAdapter.ts index 045da058cf5..5d7a44a1071 100644 --- a/apps/server/src/terminal/BunPtyAdapter.ts +++ b/apps/server/src/terminal/BunPtyAdapter.ts @@ -2,10 +2,23 @@ import * as Effect from "effect/Effect"; import * as Layer from "effect/Layer"; +import * as Schema from "effect/Schema"; import { HostProcessPlatform } from "@t3tools/shared/hostProcess"; import * as PtyAdapter from "./PtyAdapter.ts"; +export class BunPtyOperationUnavailableError extends Schema.TaggedErrorClass()( + "BunPtyOperationUnavailableError", + { + operation: Schema.Literals(["write", "resize"]), + pid: Schema.Number, + }, +) { + override get message(): string { + return `Bun PTY ${this.operation} is unavailable for process ${this.pid}.`; + } +} + class BunPtyProcess implements PtyAdapter.PtyProcess { private readonly dataListeners = new Set<(data: string) => void>(); private readonly exitListeners = new Set<(event: PtyAdapter.PtyExitEvent) => void>(); @@ -33,14 +46,14 @@ class BunPtyProcess implements PtyAdapter.PtyProcess { write(data: string): void { if (!this.process.terminal) { - throw new Error("Bun PTY terminal handle is unavailable"); + throw new BunPtyOperationUnavailableError({ operation: "write", pid: this.pid }); } this.process.terminal.write(data); } resize(cols: number, rows: number): void { if (!this.process.terminal?.resize) { - throw new Error("Bun PTY resize is unavailable"); + throw new BunPtyOperationUnavailableError({ operation: "resize", pid: this.pid }); } this.process.terminal.resize(cols, rows); }