Skip to content

Throw argument exceptions synchronously in Core's Task extensions - #181

Merged
milten89 merged 2 commits into
developfrom
fix/core-task-extensions-sync-throw
Oct 30, 2026
Merged

milten89 merged 2 commits into
developfrom
fix/core-task-extensions-sync-throw

Conversation

@milten89

Copy link
Copy Markdown
Owner

Closes #159

What

  • EnsureSuccessAsync (both overloads), MapAsync and BindAsync (both overloads) in OpenUrzednikResultExtensions are no longer async: they check their arguments and return the task of a private …CoreAsync method, so a null task or delegate throws ArgumentNullException at the call instead of faulting the returned task. XML docs list the exception.
  • ADR-0002 (dated note 2026-10-30): the synchronous argument-exception rule now covers every public method of a public type that returns a task, not only provider clients. The rule states the requirement (not async, check before creating the task); the private …CoreAsync method is the usual way. CLAUDE.md, reviewer.md and CONTRIBUTING follow.
  • Tests: one per null argument of the five methods, plus the non-generic OpenUrzednikResult.BindAsync. The existing null tests of OpenUrzednikResult<T>.BindAsync and NbpDateOnlyExtensions used ThrowAsync or an expression lambda, which also pass on a faulted task; they now use Should.Throw(() => { _ = …; }), which passes only on a synchronous throw.

Breaking change

Callers who observed the ArgumentNullException on the returned task now get it from the call. Signatures are unchanged.

Checks

  • dotnet build: 0 warnings, 0 errors
  • -f net10.0 tests, all projects: pass (Core 171, Nbp 567, Http 93, Logging 38, Diagnostics 23, DI 18, Integration 91 + 21 explicit not run)
  • Core tests -f net472: 171 pass
  • dotnet format --verify-no-changes: clean
  • dotnet pack OpenUrzednik.Packages.slnf -c Release with package validation: pass
  • reviewer agent: no blocking findings; its test and wording points are applied

🤖 Generated with Claude Code

EnsureSuccessAsync, MapAsync and BindAsync on Task<...> were async and
checked their arguments inside, so a null task or delegate came back as
a faulted task. They now check their arguments and return the task of a
private async method. ADR-0002 extends the synchronous rule to every
public method of a public type that returns a task; CLAUDE.md,
reviewer.md and CONTRIBUTING follow. Null-argument tests of the
task-returning methods now assert a synchronous throw.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@milten89 milten89 added the breaking-change Public API or behaviour break, needs a major version label Oct 30, 2026
CodeQL cs/useless-upcast: MapAsync has one overload, so explicit type
arguments replace the cast of null.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@milten89
milten89 merged commit a37fc1a into develop Oct 30, 2026
10 checks passed
@milten89
milten89 deleted the fix/core-task-extensions-sync-throw branch October 30, 2026 17:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking-change Public API or behaviour break, needs a major version

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Throw argument exceptions synchronously in Core's Task extensions

2 participants