Q59: a signal-killed command is reported as failed, not exit code 0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a3aee1940a
commit
8775c34650
2 files changed
+19
-4
No files matched your search
@@ -75,12 +75,18 @@ export function runCommand(workspaceRoot: string, command: string, options: { ti
|
||||
child.stdout.on("data", collect);
|
||||
child.stderr.on("data", collect);
|
||||
child.on("error", (error) => finish(`ERROR: ${error.message}`));
|
||||
child.on("close", (code) => {
|
||||
finish(`exit code ${code ?? 0}\n${output.text().trim() || "(no output)"}`);
|
||||
});
|
||||
child.on("close", (code, signal) => finish(formatCommandResult(code, signal, output.text())));
|
||||
});
|
||||
}
|
||||
|
||||
/** The tool result for a finished command; no exit code means it was killed, which is never success. */
|
||||
export function formatCommandResult(code: number | null, signal: NodeJS.Signals | null, text: string): string {
|
||||
const body = text.trim() || "(no output)";
|
||||
if (code !== null) return `exit code ${code}\n${body}`;
|
||||
const how = signal ? `was killed by ${signal} before it exited` : "ended without an exit code";
|
||||
return `ERROR: the command ${how}; treat it as failed.\n${body}`;
|
||||
}
|
||||
|
||||
/** Kills a process and every process it started; returns why that failed, or null. */
|
||||
function killProcessTree(pid: number | undefined): string | null {
|
||||
if (pid === undefined) return null;
|
||||
|
||||
@@ -2,7 +2,7 @@ import { mkdtempSync, readFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { describe, expect, test, vi } from "vitest";
|
||||
import { BoundedOutput, runCommand } from "../../src/main/services/workspace-command";
|
||||
import { BoundedOutput, formatCommandResult, runCommand } from "../../src/main/services/workspace-command";
|
||||
import { stopRun, withRunControl } from "../../src/main/services/run-control";
|
||||
|
||||
describe("bounded command output", () => {
|
||||
@@ -66,3 +66,12 @@ describe("run_command and run stops", () => {
|
||||
warn.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
describe("command results", () => {
|
||||
test("a signal-terminated command is reported as killed, never as exit code 0", () => {
|
||||
expect(formatCommandResult(0, null, "built")).toBe("exit code 0\nbuilt");
|
||||
expect(formatCommandResult(2, null, "")).toBe("exit code 2\n(no output)");
|
||||
expect(formatCommandResult(null, "SIGKILL", "partial")).toBe("ERROR: the command was killed by SIGKILL before it exited; treat it as failed.\npartial");
|
||||
expect(formatCommandResult(null, null, "")).toBe("ERROR: the command ended without an exit code; treat it as failed.\n(no output)");
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user