feat(api): compile-time void fallback safety - #182
Merged
Conversation
…clauses Rename the untyped, void-only fallback to FallbackAction on Shield's static factories, ShieldExtensions and ShieldBuilder. It recovers void executions only and fails a result-returning execution with InvalidOperationException, so putting that contract in the name closes the trap for cross-assembly callers KEV005 cannot see. Typed Shield<TResult>.Fallback is unchanged, and the strategy still describes as "Fallback" so pipeline descriptions read as before. Add WhenResultIsNull()/OrResultIsNull() on ShieldResultExtensions, constrained to reference types: the null check WhenResultIsDefault/OrResultIsDefault was really written for. Those stay for value types and generic code, where KEV010 — a new Info hint — now asks whether default(T) is really the failure. Document the clamping Backoff.Custom already applies to its delegate's result, and state in the composition guide that outer.Wrap(inner) and Shield.Compose(outer, inner) are the same operation. Claude-Session: https://claude.ai/code/session_01KAPqkMyQnM44sRnoYQ6hmg
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
FallbackAction adds breaking churn without improving type safety. Keep the existing Fallback API while retaining the null-result and analyzer work in PR #182.
Void fallbacks now transition fluent chains to VoidShield, preventing result execution or lifting at compile time. BREAKING CHANGE: untyped Fallback overloads return VoidShield instead of Shield. Use the VoidShield-aware DI, partition, testing, and rate-limiter APIs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fifth round of pre-release API review cleanups. The
+semver:minorprefix follows #176–#181.1. Compile-time void-fallback safety
Untyped
Fallback(...)now changes the chain's static type fromShieldtoVoidShield. The chain still starts fromShield; the type changes only when a void fallback is added, and every later fluent call preservesVoidShield.VoidShieldexposes only voidExecute/ExecuteAsync/context overloads. It cannot be assigned toShield, lifted withFor<TResult>(), wrapped into a typed shield, or passed to mixedShield.Compose(...).Wrap(...)propagates the void-only state in either direction. Result-producing recovery remainsShield.For<TResult>().Fallback(...).ShieldBuilder.Fallback(...)returnsVoidShield; later handling clauses useVoidShieldBuilder.PartitionedVoidShield<TKey>and void-aware DI registry, rate-limiter adapter, testing descriptor, and state-snapshot APIs carry the type state through integrations. The formerKEV005runtime-risk analyzer is removed because these invalid uses now fail C# compilation.Coverage includes compile-success and compile-failure contracts, all 12 public void execution forms, cancellation/deferred completion/exception identity/null guards, chaining and builder immutability, both wrap directions, partition retention, DI coexistence, rate-limiter adapters, analyzer recognition, reflection surface checks, and API baselines.
2.
WhenResultIsNull()/OrResultIsNull()New
ShieldResultExtensionsmethods constrained withwhere TResult : class?. They use the existingdefault(TResult)predicate but render as[when null result].WhenResultIsDefault/OrResultIsDefaultremain for value types and generic code.3. KEV010 (Info)
Reports
WhenResultIsDefault/OrResultIsDefaulton a known non-nullable value type, where0,false, or an empty struct may be a legitimate result.Nullable<T>and type parameters are skipped. The new null-result clauses participate in KEV007/KEV009 handling-clause analysis.4. KEV009 severity
No code change: KEV009 was already
DiagnosticSeverity.Info, documented and tested as such.5.
WrapandComposeVerified and documented that
outer.Wrap(inner)andShield.Compose(outer, inner)have identical ordering, clause sealing, naming, andTimeProviderprecedence. Mixed static composition with aVoidShieldis intentionally rejected because C# cannot conditionally change aparams Shield[]return type; useWrap(...), which preservesVoidShield.6.
Backoff.CustomclampingThe retry path already clamps negative and over-limit delays and applies
MaxDelay. XML documentation now states that behavior, with an added end-to-endMaxDelayregression test.7. Execution docs ordering
No change needed: the docs already lead with the simple execution overload and reserve explicit state for zero-closure hot paths.
Validation
dotnet build Kevlar.slnx -c Release: clean, 0 warnings/errors, includingnet10.0andnetstandard2.0API baselines.Branch note
api-review-cleanups-4belonged to merged PR #180, so this PR usesapi-review-cleanups-5.https://claude.ai/code/session_01KAPqkMyQnM44sRnoYQ6hmg