Skip to content

Engine: HandleException status classification — dead ModuleTimeoutException branch and timeout-vs-cancellation ordering #3791

Description

@thomhurst

HandleException classifies in order: exception is ModuleTimeoutExceptionIsTimeout(...)IsPipelineCancelled(...) → Failed. IsPipelineCancelled includes or ModuleTimeoutException in its type test (line 752), but that arm is unreachable — the first branch consumes every ModuleTimeoutException, so a module that times out after the pipeline has already been cancelled is classified TimedOut and re-enters CancelPipelineAndThrow rather than returning a PipelineTerminated result as the dead branch intends.

Separately, because IsTimeout (elapsed >= timeout && OCE) is evaluated before IsPipelineCancelled, an externally-cancelled module whose elapsed time happens to exceed its timeout (TimeoutHelper prioritizes external cancellation at TimeoutHelper.cs:146-149, so this race is real) is recorded as TimedOut/Failed instead of PipelineTerminated.

Fix: rework the chain into a single explicit decision table: pipeline-cancelled first, then own-timeout, then failure — and delete the dead type test.

Evidence: src/ModularPipelines/Engine/ModuleExecutionPipeline.cs:665-698,738-754


Raised by the v4 scoping audit round 3 — umbrella #3239.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low: hygiene and nice-to-haves - wheneverenhancementNew feature or requestin-progressPicked up by an agent

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions