mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-29 10:50:58 +00:00
fix: preserve windows child exit codes
This commit is contained in:
@@ -338,8 +338,8 @@ export async function runCommandWithTimeout(
|
||||
clearTimeout(timer);
|
||||
clearNoOutputTimer();
|
||||
clearCloseFallbackTimer();
|
||||
const resolvedCode = childExitState?.code ?? code;
|
||||
const resolvedSignal = childExitState?.signal ?? signal;
|
||||
const resolvedCode = childExitState?.code ?? code ?? child.exitCode ?? null;
|
||||
const resolvedSignal = childExitState?.signal ?? signal ?? child.signalCode ?? null;
|
||||
const termination = noOutputTimedOut
|
||||
? "no-output-timeout"
|
||||
: timedOut
|
||||
|
||||
@@ -17,6 +17,8 @@ let runCommandWithTimeout: typeof import("./exec.js").runCommandWithTimeout;
|
||||
let runExec: typeof import("./exec.js").runExec;
|
||||
|
||||
type MockChild = EventEmitter & {
|
||||
exitCode?: number | null;
|
||||
signalCode?: NodeJS.Signals | null;
|
||||
stdout: EventEmitter;
|
||||
stderr: EventEmitter;
|
||||
stdin: { write: ReturnType<typeof vi.fn>; end: ReturnType<typeof vi.fn> };
|
||||
@@ -25,10 +27,17 @@ type MockChild = EventEmitter & {
|
||||
killed?: boolean;
|
||||
};
|
||||
|
||||
function createMockChild(params?: { code?: number; signal?: NodeJS.Signals | null }): MockChild {
|
||||
function createMockChild(params?: {
|
||||
closeCode?: number | null;
|
||||
closeSignal?: NodeJS.Signals | null;
|
||||
exitCode?: number | null;
|
||||
signal?: NodeJS.Signals | null;
|
||||
}): MockChild {
|
||||
const child = new EventEmitter() as MockChild;
|
||||
child.stdout = new EventEmitter();
|
||||
child.stderr = new EventEmitter();
|
||||
child.exitCode = params?.exitCode ?? params?.closeCode ?? 0;
|
||||
child.signalCode = params?.signal ?? null;
|
||||
child.stdin = {
|
||||
write: vi.fn(),
|
||||
end: vi.fn(),
|
||||
@@ -37,7 +46,7 @@ function createMockChild(params?: { code?: number; signal?: NodeJS.Signals | nul
|
||||
child.pid = 1234;
|
||||
child.killed = false;
|
||||
queueMicrotask(() => {
|
||||
child.emit("close", params?.code ?? 0, params?.signal ?? null);
|
||||
child.emit("close", params?.closeCode ?? 0, params?.closeSignal ?? params?.signal ?? null);
|
||||
});
|
||||
return child;
|
||||
}
|
||||
@@ -94,6 +103,20 @@ describe("windows command wrapper behavior", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps child exitCode when close reports null on Windows npm shims", async () => {
|
||||
const platformSpy = vi.spyOn(process, "platform", "get").mockReturnValue("win32");
|
||||
const child = createMockChild({ closeCode: null, exitCode: 0 });
|
||||
|
||||
spawnMock.mockImplementation(() => child);
|
||||
|
||||
try {
|
||||
const result = await runCommandWithTimeout(["npm", "--version"], { timeoutMs: 1000 });
|
||||
expect(result.code).toBe(0);
|
||||
} finally {
|
||||
platformSpy.mockRestore();
|
||||
}
|
||||
});
|
||||
|
||||
it("uses cmd.exe wrapper with windowsVerbatimArguments in runExec for .cmd shims", async () => {
|
||||
const platformSpy = vi.spyOn(process, "platform", "get").mockReturnValue("win32");
|
||||
const expectedComSpec = process.env.ComSpec ?? "cmd.exe";
|
||||
|
||||
Reference in New Issue
Block a user