Skip to content

GH-5230 Database batch cancelled by shutdown is no longer logged as a database failure - #5232

Merged
jeremydmiller merged 1 commit into
mainfrom
gh-5230-batch-shutdown-cancellation
Oct 27, 2026
Merged

jeremydmiller merged 1 commit into
mainfrom
gh-5230-batch-shutdown-cancellation

Conversation

@jeremydmiller

Copy link
Copy Markdown
Member

Closes #5230

Problem

DatabaseBatcher.DrainAsync() cancels _internalCancellation and then joins the active batch. The in-flight DatabaseOperationBatch.ExecuteAsync() caught that cancellation in its general handler and wrapped it in DatabaseBatchCommandException, and Executor.InvokeAsync logged it at the handler's failure level (Error) before processOperationsAsync could recognise its own cancelled token.

Fix

In DatabaseOperationBatch.ExecuteAsync(), an OperationCanceledException (directly or as the inner exception) observed while the batch's own cancellation token is cancelled is treated as an orderly stop: logged at Debug, connection closed, AgentCommands.Empty returned. It never reaches the executor, so nothing is logged as an invocation failure. The same check covers opening the connection and beginning the transaction.

Unchanged: genuine SQL/connection failures, and cancellations when the token is not cancelled, are still wrapped and logged. Shutdown still joins the active batch (WaitForCompletionAsync) before disposal.

Tests

PostgresqlTests.Bugs.Bug_5230_batch_cancelled_by_shutdown_is_not_a_failure (mirrors the issue's repro, Solo mode):

  • an operation held in ReadResultsAsync until shutdown → no Error-level DatabaseBatchCommandException (fails without the fix: "Invocation of Wolverine.RDBMS.Polling.DatabaseOperationBatch failed!")
  • control: select 1 / 0; still logs a DatabaseBatchCommandException

dotnet build wolverine.slnx -c Release -f net9.0: 0 warnings, 0 errors.

🤖 Generated with Claude Code

https://claude.ai/code/session_01DCggXgxnG3EBXoR9rrq37U

… database failure

DatabaseBatcher.DrainAsync() cancels its own token before joining the active
batch. DatabaseOperationBatch.ExecuteAsync() wrapped that cancellation in a
DatabaseBatchCommandException, which the executor then logged at Error. A
cancellation observed while the batch's own token is cancelled now returns
AgentCommands.Empty (logged at Debug) instead, before the executor sees it.
Genuine SQL failures and cancellations with a live token still throw.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DCggXgxnG3EBXoR9rrq37U
@jeremydmiller
jeremydmiller merged commit 1d702ca into main Oct 27, 2026
48 checks passed
@jeremydmiller jeremydmiller mentioned this pull request Oct 27, 2026
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.

Database batch shutdown cancellation is wrapped and logged as a database failure

1 participant