mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-28 13:26:04 -06:00
fix: harden subprocess, maintenance, and output paths (#100440)
* fix(agents): contain exec output stream failures Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com> * fix(tui): contain local shell stream failures Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com> * fix(process): contain command output stream failures Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com> * fix(skills): isolate remote bin refresh failures Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com> * fix(agents): contain background subagent sweep failures Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com> * fix(skills): report directory scan failures Co-authored-by: wendy-chsy <wan.wenyan@xydigit.com> * fix(agents): classify plugin approval gateway failures Co-authored-by: 唐梓夷0668001293 <tang.ziyi@xydigit.com> * fix(exec): preserve sanitized control-byte evidence Co-authored-by: Lavya Tandel <lavya@loom.local> * fix(shared): unwrap standalone parameter tags Co-authored-by: nankingjing <1079826437@qq.com> * fix(android): fail shared capture on audio read errors Co-authored-by: NianJiuZst <3235467914@qq.com> * docs(changelog): record small bugfix sweep * fix(output): preserve sanitizer boundary semantics * test: align sanitizer and sweeper regressions * fix(terminal): preserve text after lone C1 controls --------- Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com> Co-authored-by: wendy-chsy <wan.wenyan@xydigit.com> Co-authored-by: 唐梓夷0668001293 <tang.ziyi@xydigit.com> Co-authored-by: Lavya Tandel <lavya@loom.local> Co-authored-by: nankingjing <1079826437@qq.com> Co-authored-by: NianJiuZst <3235467914@qq.com>
This commit is contained in:
committed by
GitHub
parent
8c19dbfb62
commit
a4b032e5d7
@@ -346,6 +346,20 @@ describe("runCommandWithTimeout", () => {
|
||||
},
|
||||
);
|
||||
|
||||
it("does not crash when stdout or stderr emit an error event", async () => {
|
||||
await loadExecModules({ mockSpawn: true });
|
||||
const child = createKilledChild();
|
||||
spawnMock.mockReturnValue(child);
|
||||
|
||||
const resultPromise = runCommandWithTimeout(createSilentIdleArgv(), { timeoutMs: 2_000 });
|
||||
child.stdout?.emit("error", new Error("stdout read failed"));
|
||||
child.stderr?.emit("error", new Error("stderr read failed"));
|
||||
child.emit("exit", 0, null);
|
||||
child.emit("close", 0, null);
|
||||
|
||||
await expect(resultPromise).resolves.toMatchObject({ code: 0, termination: "exit" });
|
||||
});
|
||||
|
||||
it("preserves matching output lines even when the tail capture truncates them", async () => {
|
||||
await loadExecModules();
|
||||
const result = await runCommandWithTimeout(
|
||||
|
||||
@@ -612,6 +612,10 @@ export async function runCommandWithTimeout(
|
||||
child.stdin.end();
|
||||
}
|
||||
|
||||
// Output pipes may fail independently; child exit/close remains authoritative.
|
||||
const ignoreOutputStreamError = () => {};
|
||||
child.stdout?.on("error", ignoreOutputStreamError);
|
||||
child.stderr?.on("error", ignoreOutputStreamError);
|
||||
child.stdout?.on("data", (d) => {
|
||||
appendPreservedOutputLines({
|
||||
capture: stdoutCapture,
|
||||
|
||||
Reference in New Issue
Block a user