fix: scope timeoutOf by deadline code so nesting composes (codex round 2)
Round 2 P2: timeoutOf() accepted ANY TimeoutReason, so under nesting — when the upstream handed to deadline() is itself a deadline (the RFC's named tools/execute middleware follow-up) and its outer timer fires first — AbortSignal.any preserves the outer reason and the inner bash/web would report the outer timeout as their own (timedOut / WEB_FETCH_TIMEOUT) though their local timer never expired. Add an optional code to timeoutOf; bash and web pass their own code, so a foreign timeout falls through to the upstream-cancel path.
This commit is contained in:
@@ -150,11 +150,12 @@ export class LocalBashExecutor extends BashExecutor {
|
||||
stdin: spec.stdin,
|
||||
env: spec.env,
|
||||
}, this.internals).done
|
||||
// Classify the FIRST abort reason: a TimeoutReason means the timeout cut the
|
||||
// command short; any other abort is upstream cancellation. Mutually
|
||||
// exclusive by construction — the fused signal reports one cause, not two
|
||||
// independently-latched facts.
|
||||
const timedOut = timeoutOf(d.signal) !== undefined
|
||||
// Classify the FIRST abort reason: a BASH_TIMEOUT TimeoutReason means our
|
||||
// timeout cut the command short; any other abort — an upstream cancel, or a
|
||||
// foreign (outer) deadline's timeout under nesting — is aborted. Scoping to
|
||||
// our own code keeps a nested outer deadline from reading as our timeout.
|
||||
// Mutually exclusive by construction — the fused signal reports one cause.
|
||||
const timedOut = timeoutOf(d.signal, 'BASH_TIMEOUT') !== undefined
|
||||
const aborted = d.signal.aborted && !timedOut
|
||||
return { ...outcome, timedOut, aborted, timeoutMs: spec.timeoutMs }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user