MStack.ErrorHandling 1.0.2

dotnet add package MStack.ErrorHandling --version 1.0.2
                    
NuGet\Install-Package MStack.ErrorHandling -Version 1.0.2
                    
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="MStack.ErrorHandling" Version="1.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="MStack.ErrorHandling" Version="1.0.2" />
                    
Directory.Packages.props
<PackageReference Include="MStack.ErrorHandling" />
                    
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 MStack.ErrorHandling --version 1.0.2
                    
#r "nuget: MStack.ErrorHandling, 1.0.2"
                    
#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 MStack.ErrorHandling@1.0.2
                    
#: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=MStack.ErrorHandling&version=1.0.2
                    
Install as a Cake Addin
#tool nuget:?package=MStack.ErrorHandling&version=1.0.2
                    
Install as a Cake Tool

MStack.ErrorHandling

Result pattern + RFC 9457 ProblemDetails for ASP.NET Core. One package: typed results, categorised errors, and a middleware that turns failures into well-formed HTTP responses.

NuGet License: MIT


Why

Problem What this package gives you
Returning Result<T> everywhere Result, Result<T>, Map, Bind, Match, Tap.
Reusing the same Error shape across the codebase Error(Code, Message, Category) with factory methods per category.
Mapping failures to HTTP status codes by hand ResultEndpointExtensions.ToHttpResult(httpContext) does it for you.
Standardising exception responses app.UseMStackErrorHandling() returns RFC 9457 ProblemDetails for any uncaught exception.

Install

dotnet add package MStack.ErrorHandling

Quick start

1. Register

using MStack.ErrorHandling;

builder.Services.AddMStackErrorHandling(opts =>
{
    opts.IncludeExceptionDetails = builder.Environment.IsDevelopment();
});

var app = builder.Build();
app.UseMStackErrorHandling();   // first in the pipeline

2. Return Result from your handlers

public sealed class GetUserHandler(IUserRepository users)
{
    public async Task<Result<UserDto>> HandleAsync(Guid id, CancellationToken ct)
    {
        var user = await users.GetByIdAsync(id, ct);
        return user is null
            ? Error.NotFound("User", id)
            : new UserDto(user.Id, user.Email);
    }
}

3. Map to HTTP from Minimal APIs

app.MapGet("/users/{id:guid}", async (Guid id, GetUserHandler handler, HttpContext ctx, CancellationToken ct) =>
    (await handler.HandleAsync(id, ct)).ToHttpResult(ctx));

That gives you 200 OK on success, or a fully-formed application/problem+json response on failure.


API surface

public sealed record Error(string Code, string Message, ErrorCategory Category)
{
    public static Error Validation(string code, string message);
    public static Error NotFound(string entity, object id);
    public static Error Conflict(string entity, string message);
    public static Error Forbidden(string message = "Access is forbidden.");
    public static Error Unauthorized(string message = "Authentication is required.");
    public static Error BusinessRule(string code, string message);
    public static Error Unexpected(string message = "An unexpected error occurred.");
    public static readonly Error None;
}

public class Result {
    public bool IsSuccess { get; }
    public bool IsFailure { get; }
    public Error Error { get; }
    public IReadOnlyList<Error> Errors { get; }
    public ErrorCategory Category { get; }
    public static Result Success();
    public static Result Failure(Error error);
    public static Result Failure(IEnumerable<Error> errors);
    public static Result<T> Success<T>(T value);
    public static Result<T> Failure<T>(Error error);
    public static Result<T> Failure<T>(IEnumerable<Error> errors);
    public static implicit operator Result(Error error);
}

public sealed class Result<T> : Result {
    public T Value { get; }
    public static implicit operator Result<T>(T value);
    public static implicit operator Result<T>(Error error);
}

// Functional helpers
public static class ResultExtensions {
    public static Result<TOut> Map<TIn, TOut>(this Result<TIn>, Func<TIn, TOut>);
    public static Result<TOut> Bind<TIn, TOut>(this Result<TIn>, Func<TIn, Result<TOut>>);
    public static TOut Match<TIn, TOut>(this Result<TIn>, Func<TIn, TOut>, Func<IReadOnlyList<Error>, TOut>);
    public static TOut Match<TOut>(this Result, Func<TOut>, Func<IReadOnlyList<Error>, TOut>);
    public static Result<T> Tap<T>(this Result<T>, Action<T>);
    public static Result<T> TapError<T>(this Result<T>, Action<IReadOnlyList<Error>>);
}

// Minimal API
public static class ResultEndpointExtensions {
    public static IResult ToHttpResult<T>(this Result<T>, HttpContext);
    public static IResult ToHttpResult<T>(this Result<T>, HttpContext, Func<T, IResult>);
    public static IResult ToHttpResult(this Result, HttpContext);
}

// Pipeline
public static class ServiceCollectionExtensions {
    public static IServiceCollection AddMStackErrorHandling(this IServiceCollection);
    public static IServiceCollection AddMStackErrorHandling(this IServiceCollection, Action<ErrorHandlingOptions>);
    public static IApplicationBuilder UseMStackErrorHandling(this IApplicationBuilder);
}

ErrorCategory → HTTP status

ErrorCategory HTTP Notes
Validation 400 Becomes ValidationProblemDetails
NotFound 404
Conflict 409
Forbidden 403
Unauthorized 401
BusinessRule 422 Becomes ValidationProblemDetails
Unexpected 500
None 500 Fallback — should never reach HTTP

License

MIT

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on MStack.ErrorHandling:

Package Downloads
MStack.ValueObjects

Value Object base classes for DDD plus a curated set of ready-to-use value objects (Email, Slug, Money, Cpf, Cnpj, Cep, PhoneNumberBr...). Construction returns Result<T> from MStack.ErrorHandling so failures compose naturally with the rest of your application.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.2 113 5/9/2026
1.0.1 111 5/9/2026
1.0.0 109 5/9/2026