1import { assert, describe, it } from "@effect/vitest";
2import * as Effect from "effect/Effect";
3import * as PlatformError from "effect/PlatformError";
4import { ChildProcessSpawner } from "effect/process";
5
6import * as CodexError from "../errors.ts";
7import { makeTerminationError } from "./stdio.ts";
8
9describe("Codex App Server child process termination", () => {
10 it.effect("retains the process identifier with the exit code", () =>
11 Effect.gen(function* () {
12 const error = yield* makeTerminationError({
13 pid: ChildProcessSpawner.ProcessId(51),
14 exitCode: Effect.succeed(ChildProcessSpawner.ExitCode(9)),
15 });
16
17 assert.instanceOf(error, CodexError.CodexAppServerProcessExitedError);
18 assert.equal(error.pid, 51);
19 assert.equal(error.code, 9);
20 assert.equal(error.message, "Codex App Server process exited with code 9");
21 }),
22 );
23
24 it.effect("retains the process identifier and exact exit-status cause", () =>
25 Effect.gen(function* () {
26 const rootCause = new Error("private process diagnostics");
27 const cause = PlatformError.systemError({
28 _tag: "Unknown",
29 module: "ChildProcess",
30 method: "exitCode",
31 cause: rootCause,
32 });
33 const error = yield* makeTerminationError({
34 pid: ChildProcessSpawner.ProcessId(52),
35 exitCode: Effect.fail(cause),
36 });
37
38 assert.instanceOf(error, CodexError.CodexAppServerTransportError);
39 assert.equal(error.pid, 52);
40 assert.strictEqual(error.cause, cause);
41 assert.equal(
42 error.message,
43 "Codex App Server transport operation 'read-process-exit-status' failed.",
44 );
45 assert.notInclude(error.message, rootCause.message);
46 }),
47 );
48});