Skip to content

Report an action that throws after Stop() from RethrowExceptions [patch] - #76

Merged
matt-edmondson merged 2 commits into
mainfrom
claude/intervalaction-56-rethrow-after-stop
Oct 5, 2026
Merged

matt-edmondson merged 2 commits into
mainfrom
claude/intervalaction-56-rethrow-after-stop

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #56

Problem

RethrowExceptions() only read PollingTask.Exception. An action's exception gets to the polling task only on the tick after the action faults. If Stop() was called while an action was still running, the loop exited normally and there was no later tick. The action's exception then stayed on ActionTask, and nothing ever read it. So the usual shutdown sequence, Stop() then RethrowExceptions(), silently lost the final run's failure.

Change

  • RethrowExceptions() checks a faulted ActionTask (under Lock) when the polling task hasn't faulted. It rethrows through ExceptionDispatchInfo as before, so the action's stack trace is kept.
  • On the issue's second question: Restart() still discards an unobserved action exception, the same way it already treats a faulted polling loop. The new remarks on RethrowExceptions say this, and the existing RestartDoesNotRethrowTheStaleActionException test still covers it.

Tests

  • New RethrowExceptionsReportsAnActionThatThrowsAfterStop. The action blocks on a gate. The test calls Stop(), waits for the polling loop to exit normally, then releases the action so it throws. It waits for ActionTask to finish and asserts that RethrowExceptions() throws the action's exception. It uses no fixed sleeps.
  • I reverted the fix temporarily: the new test fails with "Expected exception of exact type InvalidOperationException but no exception was thrown". With the fix, the full suite passes, 22/22 locally on net10.0.

🤖 Generated with Claude Code

https://claude.ai/code/session_01MDVSpB69ZHnwPkg4LgXgcx


Generated by Claude Code

RethrowExceptions only read PollingTask, which learns of an action's
exception on the tick after the action faults. After Stop() there is no
later tick, so the final run's failure stayed on ActionTask unobserved.
RethrowExceptions now also checks a faulted ActionTask.

Fixes #56

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDVSpB69ZHnwPkg4LgXgcx
Comment thread IntervalAction.Test/IntervalActionTests.cs Fixed
…t in the test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDVSpB69ZHnwPkg4LgXgcx
@sonarqubecloud

sonarqubecloud Bot commented Oct 5, 2026

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit cb0cdf1 into main Oct 5, 2026
14 checks passed
@matt-edmondson
matt-edmondson deleted the claude/intervalaction-56-rethrow-after-stop branch October 5, 2026 14:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

An action that throws after Stop() is called is silently lost: RethrowExceptions() reports nothing

2 participants