Skip to content

#42 validate options - #51

Merged
matthewdevenny merged 2 commits into
mainfrom
matt/42-validate-options
Jul 2, 2026
Merged

matthewdevenny merged 2 commits into
mainfrom
matt/42-validate-options

Conversation

@matthewdevenny

@matthewdevenny matthewdevenny commented Jul 1, 2026 •

Copy link
Copy Markdown
Contributor

Closes #42

Problem

A missing or whitespace BucketName threw a NullReferenceException from the NatsCache constructor. That surfaced as a confusing error at first cache use rather than a clear configuration failure at startup.

Change

Validate NatsCacheOptions through the options pattern so a bad BucketName fails fast, and replace the NullReferenceException with clear, typed exceptions.

Library (src/NatsDistributedCache)

  • NatsDistributedCacheExtensions.cs: AddNatsDistributedCache now registers AddOptions<NatsCacheOptions>().Configure(...).Validate(o => !string.IsNullOrWhiteSpace(o.BucketName), ...).ValidateOnStart(). With the Generic Host, an empty/whitespace BucketName fails at startup with a descriptive OptionsValidationException. Even without host startup validation, resolving the cache reads IOptions.Value, which runs the same validation before the constructor is reached. AddNatsHybridCache inherits this automatically (it delegates to AddNatsDistributedCache).
  • NatsCache.cs: removed the NullReferenceException throw. The constructor keeps a guard that now throws ArgumentException — this is the only backstop for the direct new NatsCache(...) path, which bypasses the options-validation pipeline (NatsCacheOptions is its own IOptions<>, so a raw instance skips .Validate()).
  • NatsCacheOptions.cs: the failure message lives in a single shared internal const referenced 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 via IStartupValidator.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 throws ArgumentException, not NullReferenceException.

Acceptance criteria

  • ✅ Empty/whitespace BucketName fails fast at startup with a descriptive OptionsValidationException.
  • ✅ No NullReferenceException path 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

Signed-off-by: Matthew DeVenny <matt@codecargo.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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() to AddNatsDistributedCache for BucketName validation.
  • Replaced the NullReferenceException path in NatsCache with an ArgumentException guard.
  • 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.

Comment thread src/NatsDistributedCache/NatsCache.cs Outdated
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>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

@matthewdevenny
matthewdevenny marked this pull request as ready for review July 1, 2026 21:24
@matthewdevenny
matthewdevenny requested a review from mtmk July 1, 2026 21:24

@mtmk mtmk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@matthewdevenny
matthewdevenny merged commit 005dcb0 into main Jul 2, 2026
3 checks passed
@matthewdevenny
matthewdevenny deleted the matt/42-validate-options branch July 2, 2026 03:14
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.

Validate options at startup instead of throwing NullReferenceException

3 participants