WTorricos.EitherUnion 1.0.2-preview.1

This is a prerelease version of WTorricos.EitherUnion.
dotnet add package WTorricos.EitherUnion --version 1.0.2-preview.1
                    
NuGet\Install-Package WTorricos.EitherUnion -Version 1.0.2-preview.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="WTorricos.EitherUnion" Version="1.0.2-preview.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="WTorricos.EitherUnion" Version="1.0.2-preview.1" />
                    
Directory.Packages.props
<PackageReference Include="WTorricos.EitherUnion" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add WTorricos.EitherUnion --version 1.0.2-preview.1
                    
#r "nuget: WTorricos.EitherUnion, 1.0.2-preview.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package WTorricos.EitherUnion@1.0.2-preview.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=WTorricos.EitherUnion&version=1.0.2-preview.1&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=WTorricos.EitherUnion&version=1.0.2-preview.1&prerelease
                    
Install as a Cake Tool

WTorricos.Either

WTorricos.Either is a .NET library for expressive, type-safe error handling with IEither<T>, Ok<T>, and Failure.

Its goal is to provide a practical union for success-or-failure workflows in modern .NET: while union support now exists in the platform, there is still no native built-in union tailored to this common error-handling shape.

Highlights

  • IEither<T> union with Ok<T> and Failure
  • Rich failure context: ErrorCode, Severity, TraceId, StackTrace, InnerError, Metadata
  • Fluent helpers: Map, FlatMap, Flatten, MapFailure, Match, Inspect, Tap, OnFailure, Filter, Void
  • Result extraction helpers: GetValueOrThrow
  • Async helpers (Task and ValueTask): MapAsync, FlatMapAsync, MatchAsync, ActionAsync
  • Extended async chaining helpers: FlattenAsync, MapFailureAsync, InspectAsync, TapAsync, OnFailureAsync, FilterAsync
  • LINQ query syntax support through Select, SelectMany, and Where

Install it from NuGet.

Getting started

using WTorricos.Either;
using System.Globalization;

IEither<int> result = new Ok<int>(42);

string text = result switch
{
    Ok<int> ok => ok.Value.ToString(CultureInfo.InvariantCulture),
    Failure failure => failure.GetDisplayMessage()
};
Failure failure = new(
    ErrorCode: "NOT_FOUND",
    Message: "User not found",
    Level: Severity.Warning,
    Timestamp: DateTime.UtcNow,
    Details: [new Detail("USER_ID", "The requested user does not exist")],
    StackTrace: Environment.StackTrace
);

IEither<int> result = failure;

Composition

LINQ syntax support for IEither<T>
This syntax intentionally excludes Tasks, and ValueTasks, since async chaining should be handled via await.

IEither<int> total =
    from first in GetFirstValue()
    from second in GetSecondValue(first)
    where second > 0
    select first + second;

Fluent syntax that supports Async flows

IEither<RefundPaymentResponse> responseEither = await Validate(request)
    .FlatMap(ValidateAmount)
    .FlatMapAsync(
        validRequest => BuildRefundContextAsync(validRequest, dbContext, cancellationToken),
        cancellationToken)
    .MapAsync(
        context => PersistRefundAsync(context, dbContext, cancellationToken),
        cancellationToken)
    .MapAsync(
        refund => new RefundPaymentResponse(refund.Id, refund.OrderId, refund.Amount, refund.Reason, refund.CreatedUtc),
        cancellationToken)
    .InspectAsync(
        onSuccess: ok => Console.WriteLine("Refund operation completed successfully {0}", ok),
        onFailure: failure => Console.WriteLine("Refund failed {0}", failure),
        cancellationToken: cancellationToken);;

ValueTask fluent syntax. Chaining is intentionally limited because the recommended practice is to explicitly await ValueTask instances.

IEither<RefundContext> refundCcontextEither = await requestEither.FlatMapAsync(
    validRequest => BuildRefundContextAsync(validRequest, dbContext, cancellationToken),
    cancellationToken);

IEither<RefundEntity> result = await refundCcontextEither.MapAsync(
    context => PersistRefundAsync(context, dbContext, cancellationToken),
    cancellationToken);

Custom failures

Custom failures are plain records that inherit from Failure.

public record NotFoundFailure(string Resource, string? TraceId = null)
    : Failure(
        ErrorCode: "NOT_FOUND_404",
        Message: $"{Resource} not found",
        Level: Severity.Warning,
        Timestamp: DateTime.UtcNow,
        Details: [],
        TraceId: TraceId,
        StackTrace: Environment.StackTrace);

Documentation

Sample API (vertical slices)

samples/Either.SampleApi demonstrates a medium-complexity minimal API with practical IEither<T> flows:

  • POST /orders uses FlatMap + FlatMapAsync
  • GET /orders/{id} uses FromNullable + MapFailure
  • POST /payments/refund uses Filter + MapAsync and returns HTTP 499 on cancellation
  • POST /payments/refund/v2 shows the Task-based async chaining flow and returns HTTP 499 on cancellation

Contributing

dotnet build WTorricos.Either.slnx
dotnet test tests\WTorricos.Either.UnitTests\WTorricos.Either.UnitTests.csproj
./build.cmd CiBuildAndTest

The library targets net11.0 preview tooling in this repository and packs as WTorricos.EitherUnion.

Product Compatible and additional computed target framework versions.
.NET net11.0 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net11.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.2-preview.1 85 7/3/2026
1.0.0-preview.1 74 6/28/2026

Release 1.0.2-preview.1. See CHANGELOG.md for details.