






















@@ -738,7 +738,14 @@ describe("kitchen-sink RPC command output capture", () => {
738738const root = mkdtempSync(path.join(tmpdir(), "openclaw-kitchen-rpc-timeout-"));
739739const scriptPath = path.join(root, "trap-term.mjs");
740740const grandchildPidPath = path.join(root, "grandchild.pid");
741+const grandchildReadyPath = path.join(root, "grandchild.ready");
741742let grandchildPid = 0;
743+const grandchildScript = [
744+"const fs = require('node:fs');",
745+"process.on('SIGTERM', () => {});",
746+"fs.writeFileSync(process.env.GRANDCHILD_READY_PATH, 'ready');",
747+"setInterval(() => {}, 1000);",
748+].join(" ");
742749743750writeFileSync(
744751scriptPath,
@@ -748,28 +755,37 @@ import fs from "node:fs";
748755749756const grandchild = spawn(process.execPath, [
750757 "-e",
751- "process.on('SIGTERM', () => {}); setInterval(() => {}, 1000);",
752-], { stdio: "ignore" });
758+ ${JSON.stringify(grandchildScript)},
759+], { env: { ...process.env, GRANDCHILD_READY_PATH: process.argv[3] }, stdio: "ignore" });
753760fs.writeFileSync(process.argv[2], String(grandchild.pid));
754761process.on("SIGTERM", () => {});
755762setInterval(() => {}, 1000);
756763`,
757764"utf8",
758765);
759766760-const runPromise = runCommand(process.execPath, [scriptPath, grandchildPidPath], {
767+const runPromise = runCommand(process.execPath, [scriptPath, grandchildPidPath, grandchildReadyPath], {
761768detached: undefined,
762769timeoutKillGraceMs: 25,
763770timeoutMs: 500,
764771});
772+const runErrorPromise = runPromise.then(
773+() => {
774+throw new Error("expected timed command to reject");
775+},
776+(error: unknown) => error,
777+);
765778766779try {
767780await waitFor(() => existsSync(grandchildPidPath));
781+await waitFor(() => existsSync(grandchildReadyPath));
768782grandchildPid = Number.parseInt(readText(grandchildPidPath), 10);
769783expect(Number.isInteger(grandchildPid)).toBe(true);
770784expect(isProcessAlive(grandchildPid)).toBe(true);
771785772-await expect(runPromise).rejects.toThrow("timed out after 500ms");
786+const runError = await runErrorPromise;
787+expect(runError).toBeInstanceOf(Error);
788+expect((runError as Error).message).toContain("timed out after 500ms");
773789await waitFor(() => !isProcessAlive(grandchildPid), 5_000);
774790} finally {
775791await runPromise.catch(() => {});
@@ -1015,7 +1031,14 @@ describe("kitchen-sink RPC caller loading", () => {
10151031const root = makeTempDir(tempDirs, "openclaw-kitchen-rpc-timeout-clean-parent-");
10161032const scriptPath = path.join(root, "term-zero-grandchild.mjs");
10171033const grandchildPidPath = path.join(root, "grandchild.pid");
1034+const grandchildReadyPath = path.join(root, "grandchild.ready");
10181035let grandchildPid = 0;
1036+const grandchildScript = [
1037+"const fs = require('node:fs');",
1038+"process.on('SIGTERM', () => {});",
1039+"fs.writeFileSync(process.env.GRANDCHILD_READY_PATH, 'ready');",
1040+"setInterval(() => {}, 1000);",
1041+].join(" ");
1019104210201043writeFileSync(
10211044scriptPath,
@@ -1025,27 +1048,36 @@ import fs from "node:fs";
1025104810261049const grandchild = spawn(process.execPath, [
10271050 "-e",
1028- "process.on('SIGTERM', () => {}); setInterval(() => {}, 1000);",
1029-], { stdio: "ignore" });
1051+ ${JSON.stringify(grandchildScript)},
1052+], { env: { ...process.env, GRANDCHILD_READY_PATH: process.argv[3] }, stdio: "ignore" });
10301053fs.writeFileSync(process.argv[2], String(grandchild.pid));
10311054process.on("SIGTERM", () => process.exit(0));
10321055setInterval(() => {}, 1000);
10331056`,
10341057"utf8",
10351058);
103610591037-const runPromise = runCommand(process.execPath, [scriptPath, grandchildPidPath], {
1060+const runPromise = runCommand(process.execPath, [scriptPath, grandchildPidPath, grandchildReadyPath], {
10381061timeoutKillGraceMs: 2_000,
1039-timeoutMs: 100,
1062+timeoutMs: 1_500,
10401063});
1064+const runErrorPromise = runPromise.then(
1065+() => {
1066+throw new Error("expected timed command to reject");
1067+},
1068+(error: unknown) => error,
1069+);
1041107010421071try {
10431072await waitFor(() => existsSync(grandchildPidPath));
1073+await waitFor(() => existsSync(grandchildReadyPath));
10441074grandchildPid = Number.parseInt(readText(grandchildPidPath), 10);
10451075expect(Number.isInteger(grandchildPid)).toBe(true);
10461076expect(isProcessAlive(grandchildPid)).toBe(true);
104710771048-await expect(runPromise).rejects.toThrow("timed out after 100ms");
1078+const runError = await runErrorPromise;
1079+expect(runError).toBeInstanceOf(Error);
1080+expect((runError as Error).message).toContain("timed out after 1500ms");
10491081await waitFor(() => !isProcessAlive(grandchildPid), 5_000);
10501082} finally {
10511083await runPromise.catch(() => {});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。