#42 validate options - #51
Merged
Merged
Conversation
Signed-off-by: Matthew DeVenny <matt@codecargo.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Implements fail-fast configuration validation for NatsCacheOptions.BucketName using the options pattern so misconfiguration surfaces as an OptionsValidationException at startup rather than a NullReferenceException at first cache use.
Changes:
- Added
Validate(...).ValidateOnStart()toAddNatsDistributedCacheforBucketNamevalidation. - Replaced the
NullReferenceExceptionpath inNatsCachewith anArgumentExceptionguard. - Added unit tests covering startup validation behavior and direct constructor behavior.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| test/UnitTests/Extensions/NatsDistributedCacheExtensionsTests.cs | Adds tests asserting startup options validation fails fast for missing BucketName, and direct construction throws a clear exception. |
| src/NatsDistributedCache/NatsDistributedCacheExtensions.cs | Registers NatsCacheOptions with predicate validation and ValidateOnStart(). |
| src/NatsDistributedCache/NatsCacheOptions.cs | Introduces a shared validation message constant for consistent error reporting. |
| src/NatsDistributedCache/NatsCache.cs | Replaces the NullReferenceException for missing BucketName with an ArgumentException guard. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Use nameof(NatsCacheOptions.BucketName) instead of nameof(optionsAccessor) so the exception reads "(Parameter 'BucketName')" and points at the actual misconfigured value rather than the accessor argument. Pin the paramName in the direct-construction test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Matthew DeVenny <matt@codecargo.com>
matthewdevenny
marked this pull request as ready for review
July 1, 2026 21:24
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.
Closes #42
Problem
A missing or whitespace
BucketNamethrew aNullReferenceExceptionfrom theNatsCacheconstructor. That surfaced as a confusing error at first cache use rather than a clear configuration failure at startup.Change
Validate
NatsCacheOptionsthrough the options pattern so a badBucketNamefails fast, and replace theNullReferenceExceptionwith clear, typed exceptions.Library (
src/NatsDistributedCache)NatsDistributedCacheExtensions.cs:AddNatsDistributedCachenow registersAddOptions<NatsCacheOptions>().Configure(...).Validate(o => !string.IsNullOrWhiteSpace(o.BucketName), ...).ValidateOnStart(). With the Generic Host, an empty/whitespaceBucketNamefails at startup with a descriptiveOptionsValidationException. Even without host startup validation, resolving the cache readsIOptions.Value, which runs the same validation before the constructor is reached.AddNatsHybridCacheinherits this automatically (it delegates toAddNatsDistributedCache).NatsCache.cs: removed theNullReferenceExceptionthrow. The constructor keeps a guard that now throwsArgumentException— this is the only backstop for the directnew NatsCache(...)path, which bypasses the options-validation pipeline (NatsCacheOptionsis its ownIOptions<>, so a raw instance skips.Validate()).NatsCacheOptions.cs: the failure message lives in a single sharedinternal constreferenced by both the DI validator and the constructor guard, so the two paths can't drift.Tests (
test/UnitTests)AddNatsCache_MissingBucketName_FailsValidationOnStart— null/empty/whitespace fail fast viaIStartupValidator.Validate()(the mechanism the host invokes), with the descriptive message.AddNatsCache_ValidBucketName_PassesValidationOnStart— a valid bucket name passes startup validation.NatsCache_DirectConstruction_MissingBucketName_ThrowsArgumentException— the direct-construction path throwsArgumentException, notNullReferenceException.Acceptance criteria
BucketNamefails fast at startup with a descriptiveOptionsValidationException.NullReferenceExceptionpath remains.Verification
dotnet test test/UnitTests→ 69/69 passing on net8.0 + net10.0.dotnet build -p:TreatWarningsAsErrors=true→ 0 warnings (net8.0 + net10.0).🤖 Generated with Claude Code