fix(utils): contained ptree timeout rejections
- Observed timed-out child lifecycle failures without altering awaited rejection semantics. - Added coverage for callers that settle without observing the lifecycle promise. Fixes #6635
This commit is contained in:
@@ -2,6 +2,10 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Contained timed-out child lifecycle rejections so `ptree` callers cannot leak an unhandled `TimeoutError` after settling ([#6635](https://github.com/can1357/oh-my-pi/issues/6635)).
|
||||
|
||||
## [17.0.9] - 2026-07-23
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
@@ -309,6 +309,7 @@ export class ChildProcess<In extends InMask = InMask> {
|
||||
|
||||
attachTimeout(ms: number): void {
|
||||
if (ms <= 0 || this.proc.killed) return;
|
||||
this.#exited.catch(() => {});
|
||||
Promise.race([
|
||||
Bun.sleep(ms).then(() => true),
|
||||
this.proc.exited.then(
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import { describe, expect, it } from "bun:test";
|
||||
import { spawn, TimeoutError } from "@oh-my-pi/pi-utils/ptree";
|
||||
|
||||
describe("ptree timeout", () => {
|
||||
it("contains the lifecycle rejection when the caller does not observe exited", async () => {
|
||||
const unhandled = new Set<unknown>();
|
||||
const onUnhandled = (reason: unknown) => {
|
||||
unhandled.add(reason);
|
||||
};
|
||||
process.on("unhandledRejection", onUnhandled);
|
||||
|
||||
try {
|
||||
// Bun's subprocess timeout uses the platform clock; fake timers cannot drive this lifecycle.
|
||||
using child = spawn(["bun", "-e", "Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0)"], {
|
||||
timeout: 20,
|
||||
});
|
||||
await child.nothrow().text();
|
||||
await child.proc.exited;
|
||||
const nextTurn = Promise.withResolvers<void>();
|
||||
setImmediate(nextTurn.resolve);
|
||||
await nextTurn.promise;
|
||||
|
||||
expect(child.exitReason).toBeInstanceOf(TimeoutError);
|
||||
expect(unhandled.has(child.exitReason)).toBe(false);
|
||||
} finally {
|
||||
process.off("unhandledRejection", onUnhandled);
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user