Skip to content

Action throwing OperationCanceledException/TaskCanceledException silently stops the polling loop; RethrowExceptions() reports nothing #66

Description

@matt-edmondson

What's wrong

If the user's Action throws, the next tick's TryRun() rethrows that exception inside the polling loop's async lambda (IntervalAction/IntervalAction.cs, ~lines 221–240). When an async method ends with an OperationCanceledException, its task becomes Canceled, not Faulted. TaskCanceledException derives from OperationCanceledException, and HttpClient throws it on a timeout, so this is not a rare case.

Once that happens, PollingTask.Status == Canceled and PollingTask.Exception == null. RethrowExceptions() (line ~299) only looks at PollingTask.Exception, so it returns normally. The loop has stopped for good, but ShouldPoll still reads true and nothing reports the failure.

Repro

PollingInterval = 20ms, ActionInterval = 0, Action = () => throw new TaskCanceledException("http timeout"). After 500 ms:

  • the action has run once
  • the polling task is Canceled
  • RethrowExceptions() throws nothing

For comparison, the same setup throwing InvalidOperationException leaves the task Faulted, and RethrowExceptions() throws as documented. Both results were confirmed with a temporary MSTest against main (f6424e3).

Suggested fix

Take either approach:

  • In RethrowExceptions(), also handle PollingTask.IsCanceled and rethrow the action's original exception. The faulted ActionTask still holds it: ExceptionDispatchInfo.Capture(ActionTask.Exception!.GetBaseException()).Throw().
  • Or stop an action failure from surfacing as cancellation. Have the loop catch the OperationCanceledException that TryRun rethrows and turn it into a fault, so PollingTask ends up Faulted.

Acceptance: add a regression test in which the action throws TaskCanceledException and RethrowExceptions() throws it.

Activity

  1. matt-edmondson commented on Sep 28, 2026

    @matt-edmondson
    ContributorAuthor

    Triage


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't workingreadyFully specified; implement as written

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions