Skip to content

Annotate Result.Fail (and other factory methods) with [Pure] attribute to catch ignored return values #235

@serber

Description

@serber

Issue

Example of code

var loadUserResult = await LoadUserAsync(userId, cancellationToken);
if (loadUserResult.IsFailed)
{
    ... Some extra actions
    Result.Fail("Error loading user");   // Here is return missed and failure is ignored
}

... Some extra actions
return Result.Ok(user);

Because Result.Fail(...) wasn’t returned, the failure is dropped and the method continues as if everything succeeded.

Proposal

Mark all Result.Fail(…) overloads (and other pure factory methods such as Result.Ok, etc.) with the [Pure] attribute from System.Diagnostics.Contracts. This enables developers to turn on the CA1806: Do not ignore method return value rule and catch any unused results at compile time.

https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.contracts.pureattribute
https://learn.microsoft.com/en-gb/dotnet/fundamentals/code-analysis/quality-rules/ca1806

Developers then add to their .editorconfig:

dotnet_diagnostic.CA1806.severity = error

Benefits

  • Compile-time safety: Errors whenever a pure factory call isn’t used (e.g. missing return).
  • Improved developer experience: Prevents dropped failures and enforces correct control flow.

With [Pure] on Result.Fail, this code

if (loadUserResult.IsFailed)
{
    Result.Fail("Error loading user");
}

produces:

Warning CA1806: The result of the method Result.Fail is ignored; consider using its return value.

and guides developers to write:

if (loadUserResult.IsFailed)
{
    return Result.Fail("Error loading user");
}

Request

  1. Add [Pure] to all relevant side-effect-free factory methods in the Result class.
  2. Document this in the README so that consumers know they can enable CA1806 for extra safety.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions