ErrorLens.ErrorHandling 1.1.0

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

ErrorLens.ErrorHandling

NuGet Build License: MIT .NET 6.0+

Automatic, consistent error handling for ASP.NET Core APIs. Transform unhandled exceptions into structured JSON responses with zero configuration — or customize everything via attributes, configuration files, and custom handlers.

Features

  • Zero-Config Exception Handling — Unhandled exceptions return structured JSON error responses out of the box
  • Validation Error Details — Field-level errors with property names, messages, and rejected values
  • Custom JSON Field Names — Rename any response field (codetype, messagedetail, etc.)
  • YAML & JSON Configuration — Configure error codes, messages, HTTP statuses via appsettings.json or errorhandling.yml
  • Custom Exception Attributes[ResponseErrorCode], [ResponseStatus], [ResponseErrorProperty]
  • Custom Exception Handlers — Register IApiExceptionHandler implementations with priority ordering
  • Response Customization — Add global properties (traceId, timestamp) via IApiErrorResponseCustomizer
  • RFC 9457 Problem Details — Opt-in application/problem+json compliant responses
  • Configurable Logging — Control log levels and stack trace verbosity per HTTP status code
  • Multi-Target Support — .NET 6.0, 7.0, 8.0, 9.0, and 10.0

Installation

dotnet add package ErrorLens.ErrorHandling

Quick Start

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddErrorHandling();

var app = builder.Build();
app.UseErrorHandling();
app.MapControllers();
app.Run();

All unhandled exceptions now return structured JSON:

{
  "code": "INVALID_OPERATION",
  "message": "The operation is not valid."
}

Configuration

JSON (appsettings.json)

{
  "ErrorHandling": {
    "Enabled": true,
    "HttpStatusInJsonResponse": true,
    "DefaultErrorCodeStrategy": "AllCaps",
    "AddPathToError": true,
    "OverrideModelStateValidation": true,
    "SearchSuperClassHierarchy": true,
    "ExceptionLogging": "WithStacktrace",

    "JsonFieldNames": {
      "Code": "type",
      "Message": "detail"
    },

    "HttpStatuses": {
      "MyApp.UserNotFoundException": 404,
      "MyApp.DuplicateEmailException": 409
    },

    "Codes": {
      "MyApp.UserNotFoundException": "USER_NOT_FOUND",
      "email.Required": "EMAIL_REQUIRED"
    },

    "Messages": {
      "MyApp.UserNotFoundException": "The requested user was not found"
    },

    "LogLevels": {
      "4xx": "Warning",
      "5xx": "Error",
      "404": "Debug"
    }
  }
}

YAML (errorhandling.yml)

ErrorHandling:
  Enabled: true
  HttpStatusInJsonResponse: true
  DefaultErrorCodeStrategy: AllCaps
  AddPathToError: true
  OverrideModelStateValidation: true
  SearchSuperClassHierarchy: true
  ExceptionLogging: WithStacktrace

  JsonFieldNames:
    Code: type
    Message: detail

  HttpStatuses:
    MyApp.UserNotFoundException: 404
    MyApp.DuplicateEmailException: 409

  Codes:
    MyApp.UserNotFoundException: USER_NOT_FOUND
    email.Required: EMAIL_REQUIRED

  Messages:
    MyApp.UserNotFoundException: The requested user was not found

  LogLevels:
    4xx: Warning
    5xx: Error
    404: Debug

To use YAML configuration:

builder.Configuration.AddYamlErrorHandling("errorhandling.yml");
builder.Services.AddErrorHandling(builder.Configuration);

A full YAML template with all options is available at docs/errorhandling-template.yml.

Custom JSON Field Names

Rename any JSON property in error responses to match your API conventions:

ErrorHandling:
  JsonFieldNames:
    Code: type            # "code" → "type"
    Message: detail       # "message" → "detail"
    Status: statusCode    # "status" → "statusCode"
    FieldErrors: fields   # "fieldErrors" → "fields"
    Property: field       # "property" → "field"

Before:

{ "code": "USER_NOT_FOUND", "message": "User not found" }

After:

{ "type": "USER_NOT_FOUND", "detail": "User not found" }

Custom Exception Attributes

Decorate exception classes with attributes to control error responses:

[ResponseErrorCode("USER_NOT_FOUND")]
[ResponseStatus(HttpStatusCode.NotFound)]
public class UserNotFoundException : Exception
{
    [ResponseErrorProperty("userId")]
    public string UserId { get; }

    public UserNotFoundException(string userId)
        : base($"User {userId} not found") => UserId = userId;
}

Response:

{
  "code": "USER_NOT_FOUND",
  "message": "User abc-123 not found",
  "userId": "abc-123"
}

Custom Exception Handlers

Register custom handlers for specialized exception types:

public class InfrastructureExceptionHandler : IApiExceptionHandler
{
    public int Order => 50; // Lower = higher priority (runs before built-in handlers at 100+)

    public bool CanHandle(Exception ex) => ex is DatabaseTimeoutException;

    public ApiErrorResponse Handle(Exception ex) =>
        new(HttpStatusCode.ServiceUnavailable, "DATABASE_TIMEOUT", ex.Message);
}

// Register
builder.Services.AddExceptionHandler<InfrastructureExceptionHandler>();

Response Customization

Add global properties to all error responses:

public class TraceIdCustomizer : IApiErrorResponseCustomizer
{
    public void Customize(ApiErrorResponse response)
    {
        response.AddProperty("traceId", Activity.Current?.Id);
        response.AddProperty("timestamp", DateTime.UtcNow.ToString("o"));
    }
}

// Register
builder.Services.AddErrorResponseCustomizer<TraceIdCustomizer>();

Validation Errors

Validation exceptions automatically include field-level details. Enable OverrideModelStateValidation: true to intercept [ApiController] automatic validation and use ErrorLens structured format:

{
  "code": "VALIDATION_FAILED",
  "message": "Validation failed",
  "fieldErrors": [
    {
      "code": "REQUIRED_NOT_NULL",
      "property": "email",
      "message": "Email is required",
      "rejectedValue": null,
      "path": "email"
    }
  ]
}

RFC 9457 Problem Details

Enable RFC 9457 compliant application/problem+json responses:

{
  "ErrorHandling": {
    "UseProblemDetailFormat": true,
    "ProblemDetailTypePrefix": "https://api.example.com/errors/",
    "ProblemDetailConvertToKebabCase": true
  }
}

Response:

{
  "type": "https://api.example.com/errors/user-not-found",
  "title": "Not Found",
  "status": 404,
  "detail": "User abc-123 not found",
  "code": "USER_NOT_FOUND"
}

Logging

Control logging verbosity per HTTP status code or exception type:

ErrorHandling:
  ExceptionLogging: WithStacktrace   # None | MessageOnly | WithStacktrace
  LogLevels:
    4xx: Warning
    5xx: Error
    404: Debug
  FullStacktraceHttpStatuses:
    - 5xx
  FullStacktraceClasses:
    - MyApp.CriticalException

Error Code Strategies

Strategy Example Input Output
AllCaps (default) UserNotFoundException USER_NOT_FOUND
FullQualifiedName UserNotFoundException MyApp.Exceptions.UserNotFoundException

Default HTTP Status Mappings

Exception Type HTTP Status
ArgumentException / ArgumentNullException 400 Bad Request
InvalidOperationException 400 Bad Request
FormatException 400 Bad Request
OperationCanceledException 400 Bad Request
UnauthorizedAccessException 401 Unauthorized
KeyNotFoundException 404 Not Found
FileNotFoundException 404 Not Found
DirectoryNotFoundException 404 Not Found
TimeoutException 408 Request Timeout
NotImplementedException 501 Not Implemented
All others 500 Internal Server Error

Samples

Sample Description
MinimalApiSample Zero-config minimal API setup
FullApiSample Controllers, custom handlers, response customizers
ShowcaseSample All features: YAML config, custom field names, attributes, custom handlers, Problem Details

Documentation

🤝 Contributing

See CONTRIBUTING.md for guidelines.

License

MIT License — see LICENSE for details.

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  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.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on ErrorLens.ErrorHandling:

Package Downloads
ErrorLens.ErrorHandling.OpenApi

Microsoft.AspNetCore.OpenApi integration for ErrorLens.ErrorHandling — automatically adds error response schemas to your OpenAPI documentation (.NET 9+).

ErrorLens.ErrorHandling.Swashbuckle

Swashbuckle integration for ErrorLens.ErrorHandling — automatically adds error response schemas to your Swagger/OpenAPI documentation.

ErrorLens.ErrorHandling.FluentValidation

FluentValidation integration for ErrorLens.ErrorHandling — automatically catches FluentValidation.ValidationException and maps failures to structured API error responses with field errors, error codes, and rejected values.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.4.0 136 2/28/2026
1.3.1 125 2/21/2026
1.3.0 133 2/16/2026
1.1.1 91 2/12/2026
1.1.0 80 2/11/2026
1.0.0 118 2/10/2026

v1.1.0:
- Custom JSON field names (rename code→type, message→detail, etc.)
- YAML configuration support via AddYamlErrorHandling()
- OverrideModelStateValidation option for [ApiController] validation interception
- ModelStateValidationExceptionHandler with structured fieldErrors format
- Professional documentation with AsciiDoc
- 175 tests (up from 142)

Full changelog: https://github.com/AhmedV20/errorLens-errorhandling/blob/main/CHANGELOG.md