From 65697c58606b8c86c713ae1bed41a962f681e6e9 Mon Sep 17 00:00:00 2001
From: Chris Wolfgang <210299580+Chris-Wolfgang@users.noreply.github.com>
Date: Sat, 27 Jun 2026 22:09:26 -0400
Subject: [PATCH] chore(review): trivial fixes from AI code-review pass
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Batch of low-risk fixes surfaced by the v0.3.3 AI code-review pass
(#128). Larger findings are filed as separate Tier-2 sub-issues.
Source — XML doc + small wording
- Result.cs: class summaries reworded so they no longer claim the
types are only produced by Try.Run (they're also used directly as
repository / validation return types).
- Result.cs: Failure() exception message now matches the protected
ctor wording ("cannot be null, empty, or whitespace.") and the
exception cref blocks point at .
- Result.cs: added to Success() / Failure() factories;
Result.Success(value) now documents its + ;
the private Result.Value getter's mentions throw-on-
failure inline (was only in ), and the
text is a complete sentence.
- Try.cs: RunAsync summary now says "asynchronously" (parity with
the Action variant); Run summary differentiates from Run by
mentioning the return value.
Tests — naming convention drift
- ResultTests.cs: two tests whose names said "throw_Invalid-
OperationException" actually assert ArgumentException; renamed
to match observed behavior.
- RunFuncTests.cs: 8 PascalCase test names migrated to the
CLAUDE.md canonical snake_case
Method_when_condition_expected_result pattern; the one named
FunctionNullableInt_WithExceptionThrowingFunction_ReturnsDefault
actually verifies Value-access throws on failed result and is
renamed accordingly.
csproj hygiene
- src csproj: added per Directory.Build.props's
per-repo expectation; normalized mixed-tabs/spaces indent.
- tests csproj: dropped dead netcoreapp3.1
block (netcoreapp3.1 is not in , so the group
never matched); dropped stale 0.3.0 (test
project is IsPackable=false, the version field was unused).
Examples
- FSharp.DotNet8.Example/Program.fs: module name said
FSharp.DotNet462.Example — copy-paste bug from the F#/.NET 4.6.2
sibling; renamed to FSharp.DotNet8.Example.
Docs
- docs/DOCFX-VERSION-PICKER.md: stripped a "no DateTime-Extensions
paths leak" cross-repo reference that was carried over from the
canonical fanout; replaced with generic wording.
Out-of-scope follow-ups filed as Tier-2 sub-issues of #128:
- xunit.runner.visualstudio 3.0.0 + xunit 2.9.3 mismatch on
net8/9/10 (CLAUDE.md violation, behaviour change)
- PublicApi/modern/PublicAPI.Shipped.txt missing
Result.Value.get -> T? entry (needs RS0016 sweep)
- benchmarks csproj net8.0 → net10.0 (perf picture changes)
- README database example uses sync IO inside Try.Run (opinion)
- tests csproj/dir naming mismatch
(Wolfgang.TryPattern.Tests.Unit vs Wolfgang.TryPattern.Tests)
Closes #128
---
docs/DOCFX-VERSION-PICKER.md | 4 +-
examples/FSharp.DotNet8.Example/Program.fs | 2 +-
src/Wolfgang.TryPattern/Result.cs | 51 ++++++++++++-------
src/Wolfgang.TryPattern/Try.cs | 10 ++--
.../Wolfgang.TryPattern.csproj | 49 +++++++++---------
.../Wolfgang.TryPattern.Tests/ResultTests.cs | 4 +-
.../Wolfgang.TryPattern.Tests/RunFuncTests.cs | 16 +++---
.../Wolfgang.TryPattern.Tests.Unit.csproj | 18 -------
8 files changed, 76 insertions(+), 78 deletions(-)
diff --git a/docs/DOCFX-VERSION-PICKER.md b/docs/DOCFX-VERSION-PICKER.md
index 8713cbe..4e39e86 100644
--- a/docs/DOCFX-VERSION-PICKER.md
+++ b/docs/DOCFX-VERSION-PICKER.md
@@ -87,8 +87,8 @@ Committed as `[]` (empty array). The `docfx.yaml` workflow regenerates
the real `versions.json` at deploy time from the set of actual `v*`
tags that have versioned docs deployed (D6 derivation) and writes it
to the gh-pages site root. The empty stub is the fanout-safe default —
-no DateTime-Extensions paths leak into other repos when this folder is
-synced fleet-wide.
+no repo-specific version paths leak into other repos when this folder
+is synced fleet-wide.
**Local picker testing** requires populating `versions.json` manually
with mock entries (see "Testing locally" below). The picker
diff --git a/examples/FSharp.DotNet8.Example/Program.fs b/examples/FSharp.DotNet8.Example/Program.fs
index 18b22fd..cb79bef 100644
--- a/examples/FSharp.DotNet8.Example/Program.fs
+++ b/examples/FSharp.DotNet8.Example/Program.fs
@@ -1,4 +1,4 @@
-module FSharp.DotNet462.Example
+module FSharp.DotNet8.Example
open System
open System.IO
diff --git a/src/Wolfgang.TryPattern/Result.cs b/src/Wolfgang.TryPattern/Result.cs
index f791e12..1883ca4 100644
--- a/src/Wolfgang.TryPattern/Result.cs
+++ b/src/Wolfgang.TryPattern/Result.cs
@@ -7,10 +7,14 @@ namespace Wolfgang.TryPattern;
///
-/// The result of executing an . Contains properties indicating whether the operation
-/// succeeded or failed. If the operation failed the property will contain
-/// a message as to why.
+/// Represents the outcome of an operation. Contains properties indicating whether the operation
+/// succeeded or failed. If the operation failed the property will
+/// contain a message as to why.
///
+///
+/// Commonly produced by , but also useful directly as a return type
+/// from validation helpers, repository methods, and other service-layer code.
+///
public class Result
{
///
@@ -55,13 +59,14 @@ protected Result
///
- /// Creates a failed Result with the specified error Message.
+ /// Creates a failed with the specified error message.
///
/// The error message indicating the reason for failure.
- /// errorMessage is null, empty, or whitespace
+ /// A failed whose is set to .
+ /// is null, empty, or whitespace.
public static Result Failure(string errorMessage) =>
string.IsNullOrWhiteSpace(errorMessage)
- ? throw new ArgumentException("errorMessage cannot be empty", nameof(errorMessage))
+ ? throw new ArgumentException("errorMessage cannot be null, empty, or whitespace.", nameof(errorMessage))
: new Result(succeeded: false, errorMessage);
@@ -73,6 +78,7 @@ public static Result Failure(string errorMessage) =>
///
/// Creates a successful .
///
+ /// A successful .
///
/// Returns a cached singleton instance. is immutable, so reusing
/// the same instance is safe and avoids per-call allocations on hot paths. Callers must
@@ -102,7 +108,7 @@ public static Result Failure(string errorMessage) =>
///
- /// The error message describing why the operation failed. Otherwise, an empty string if the operation succeeded.
+ /// Gets the error message describing why the operation failed, or an empty string if the operation succeeded.
///
public string? ErrorMessage { get; }
@@ -263,11 +269,17 @@ public static bool AllSucceeded([NotNull] params Result[]? results)
///
-/// The result of executing an . Contains properties indicating whether the operation
-/// or . If the operation failed the
-/// property will contain a message as to why. If the operation succeeded the
-/// property will contain the return value from the function.
+/// Represents the outcome of an operation that produces a value of type .
+/// Contains properties indicating whether the operation or
+/// . If the operation failed the property
+/// will contain a message as to why. If the operation succeeded the
+/// property will contain the returned value.
///
+/// The type of value returned on success.
+///
+/// Commonly produced by , but also useful directly as a return type
+/// from repository, service, or validation code that wants to surface a value-or-error outcome.
+///
[System.Diagnostics.CodeAnalysis.SuppressMessage(
"Design",
"CA1000:Do not declare static members on generic types",
@@ -306,27 +318,30 @@ public class Result : Result
///
- /// Creates a failed Result with the specified error message.
+ /// Creates a failed with the specified error message.
///
/// The error message indicating the reason for failure.
- /// errorMessage is null, empty, or whitespace
+ /// A failed whose is set to .
+ /// is null, empty, or whitespace.
#if NET5_0_OR_GREATER
public static new Result Failure(string errorMessage) =>
string.IsNullOrWhiteSpace(errorMessage)
- ? throw new ArgumentException("errorMessage cannot be empty", nameof(errorMessage))
+ ? throw new ArgumentException("errorMessage cannot be null, empty, or whitespace.", nameof(errorMessage))
: new Result(succeeded: false, errorMessage, default!);
#else
public static new Result Failure(string errorMessage) =>
string.IsNullOrWhiteSpace(errorMessage)
- ? throw new ArgumentException("errorMessage cannot be empty", nameof(errorMessage))
+ ? throw new ArgumentException("errorMessage cannot be null, empty, or whitespace.", nameof(errorMessage))
: new Result(succeeded: false, errorMessage, default!);
#endif
///
- /// Creates a successful with specified value.
+ /// Creates a successful with the specified value.
///
+ /// The value produced by the operation.
+ /// A successful whose is .
#if NET5_0_OR_GREATER
public static Result Success(T? value) => new(succeeded: true, string.Empty, value);
#else
@@ -336,9 +351,9 @@ public class Result : Result
///
- /// The value produced by the operation if it succeeded.
+ /// Gets the value produced by the operation if it succeeded; throws if the operation failed.
///
- /// Retrieving this property if the operation failed
+ /// Thrown when this property is accessed after the operation has failed.
#if NET5_0_OR_GREATER
public T? Value => Failed
? throw new InvalidOperationException("Cannot access the Value of a failed Result.")
diff --git a/src/Wolfgang.TryPattern/Try.cs b/src/Wolfgang.TryPattern/Try.cs
index 07de954..fbe654c 100644
--- a/src/Wolfgang.TryPattern/Try.cs
+++ b/src/Wolfgang.TryPattern/Try.cs
@@ -41,13 +41,13 @@ public static Result Run([NotNull] Action? action)
///
- /// Executes the specified function, catching any exception that may occur.
+ /// Executes the specified function and returns its result, catching any exception that may occur.
///
/// The return type of the function.
/// The function to execute.
///
- /// A indicating if the function was successful or not and the result of
- /// the function if it was.
+ /// A successful wrapping the function's return value, or a failed
+ /// whose is the caught exception's message.
///
/// is null.
#if NET5_0_OR_GREATER
@@ -135,10 +135,10 @@ public static async Task RunAsync([NotNull] Action? action, Cancellation
///
- /// Executes the specified function, catching any exception that may occur.
+ /// Executes the specified asynchronous function, catching any exception that may occur.
///
/// The return type of the function.
- /// The function to execute.
+ /// The asynchronous function to execute.
///
/// A that is checked before is
/// invoked. If cancellation is already requested, an
diff --git a/src/Wolfgang.TryPattern/Wolfgang.TryPattern.csproj b/src/Wolfgang.TryPattern/Wolfgang.TryPattern.csproj
index cd4be5d..3b930fd 100644
--- a/src/Wolfgang.TryPattern/Wolfgang.TryPattern.csproj
+++ b/src/Wolfgang.TryPattern/Wolfgang.TryPattern.csproj
@@ -1,32 +1,33 @@
-
+
- net462;netstandard2.0;net8.0;net10.0
- 14
- 0.3.2
-
- 1.0.0.0
- $([System.Text.RegularExpressions.Regex]::Replace("$(Version)", "[-+].*$", "")).0
- $(AssemblyName)
- A .NET library demonstrating the Try pattern for structured error handling and result types.
- https://github.com/Chris-Wolfgang/Try-Pattern
- https://github.com/Chris-Wolfgang/Try-Pattern.git
- README.md
- MIT
- True
- True
- False
- icon.png
+ net462;netstandard2.0;net8.0;net10.0
+ 14
+ 0.3.2
+
+ 1.0.0.0
+ $([System.Text.RegularExpressions.Regex]::Replace("$(Version)", "[-+].*$", "")).0
+ $(AssemblyName)
+ A .NET library demonstrating the Try pattern for structured error handling and result types.
+ try;result;error-handling;exception-handling;functional;railway-oriented;dotnet
+ https://github.com/Chris-Wolfgang/Try-Pattern
+ https://github.com/Chris-Wolfgang/Try-Pattern.git
+ README.md
+ MIT
+ True
+ True
+ False
+ icon.png
+ '$(TargetFramework)' == 'net8.0' OR
+ '$(TargetFramework)' == 'net10.0'
+ ">
enable
diff --git a/tests/Wolfgang.TryPattern.Tests/ResultTests.cs b/tests/Wolfgang.TryPattern.Tests/ResultTests.cs
index daa1dfe..9482205 100644
--- a/tests/Wolfgang.TryPattern.Tests/ResultTests.cs
+++ b/tests/Wolfgang.TryPattern.Tests/ResultTests.cs
@@ -18,7 +18,7 @@ public void Ctor_when_passed_true_and_empty_string_does_not_throw_Exception()
[InlineData(null)]
[InlineData(" ")]
[InlineData("Test error")]
- public void Ctor_when_passed_true_and_non_empty_string_throw_InvalidOperationException(string? message)
+ public void Ctor_when_passed_true_and_non_empty_string_throws_ArgumentException(string? message)
{
var ex = Assert.Throws(() => new TestResult(succeeded: true, message));
Assert.Equal("errorMessage", ex.ParamName);
@@ -38,7 +38,7 @@ public void Ctor_when_passed_false_and_message_does_not_throw_Exception()
[InlineData(null)]
[InlineData(" ")]
[InlineData("")]
- public void Ctor_when_passed_false_and_no_message_throw_InvalidOperationException(string? message)
+ public void Ctor_when_passed_false_and_no_message_throws_ArgumentException(string? message)
{
var ex = Assert.Throws(() => new TestResult(succeeded: false, message));
Assert.Equal("errorMessage", ex.ParamName);
diff --git a/tests/Wolfgang.TryPattern.Tests/RunFuncTests.cs b/tests/Wolfgang.TryPattern.Tests/RunFuncTests.cs
index db8584b..0ef76b7 100644
--- a/tests/Wolfgang.TryPattern.Tests/RunFuncTests.cs
+++ b/tests/Wolfgang.TryPattern.Tests/RunFuncTests.cs
@@ -6,7 +6,7 @@ namespace Wolfgang.TryPattern.Tests;
public class RunFuncTests
{
[Fact]
- public void Run_Func_WithNullFunction_ThrowsArgumentNullException()
+ public void Run_Func_when_function_is_null_throws_ArgumentNullException()
{
// Arrange
Func? nullFunction = null;
@@ -18,7 +18,7 @@ public void Run_Func_WithNullFunction_ThrowsArgumentNullException()
[Fact]
- public void Run_Func_WithSuccessfulFunctionOfInt_ReturnsResult()
+ public void Run_Func_when_int_function_succeeds_returns_successful_Result()
{
// Arrange
const int expectedValue = 42;
@@ -37,7 +37,7 @@ public void Run_Func_WithSuccessfulFunctionOfInt_ReturnsResult()
[Fact]
- public void Run_Func_WithSuccessfulFunctionOfNullableInt_ReturnsResult()
+ public void Run_Func_when_nullable_int_function_succeeds_returns_successful_Result()
{
// Arrange
var expectedValue = 42;
@@ -56,7 +56,7 @@ public void Run_Func_WithSuccessfulFunctionOfNullableInt_ReturnsResult()
[Fact]
- public void Run_Func_WithStringFunction_ReturnsResult()
+ public void Run_Func_when_string_function_succeeds_returns_successful_Result()
{
// Arrange
const string expectedValue = "Hello, World!";
@@ -75,7 +75,7 @@ public void Run_Func_WithStringFunction_ReturnsResult()
[Fact]
- public void Run_Func_WithNullableStringFunction_ReturnsResult()
+ public void Run_Func_when_nullable_string_function_succeeds_returns_successful_Result()
{
// Arrange
const string expectedValue = "Hello, World!";
@@ -94,7 +94,7 @@ public void Run_Func_WithNullableStringFunction_ReturnsResult()
[Fact]
- public void Run_Func_WithObjectFunction_ReturnsResult()
+ public void Run_Func_when_object_function_succeeds_returns_successful_Result()
{
// Arrange
var expectedValue = new object();
@@ -113,7 +113,7 @@ public void Run_Func_WithObjectFunction_ReturnsResult()
[Fact]
- public void FunctionNullableInt_WithExceptionThrowingFunction_ReturnsDefault()
+ public void Run_Func_when_nullable_int_function_throws_returns_failed_Result_whose_Value_access_throws()
{
// Arrange
static int? Function() => throw new InvalidOperationException("Test exception");
@@ -149,7 +149,7 @@ public void Run_Func_reference_type_returns_Result_with_correct_properties()
[Fact]
- public void Run_Func_WithMultipleCalls_HandlesEachIndependently()
+ public void Run_Func_when_called_multiple_times_handles_each_independently()
{
// Arrange
var callCount = 0;
diff --git a/tests/Wolfgang.TryPattern.Tests/Wolfgang.TryPattern.Tests.Unit.csproj b/tests/Wolfgang.TryPattern.Tests/Wolfgang.TryPattern.Tests.Unit.csproj
index ba1906d..1cfd526 100644
--- a/tests/Wolfgang.TryPattern.Tests/Wolfgang.TryPattern.Tests.Unit.csproj
+++ b/tests/Wolfgang.TryPattern.Tests/Wolfgang.TryPattern.Tests.Unit.csproj
@@ -2,7 +2,6 @@
net462;net472;net48;net481;net5.0;net6.0;net7.0;net8.0;net9.0;net10.0
- 0.3.0
latest
enable
false
@@ -61,23 +60,6 @@
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-