Skip to content

TechNobre/PowerUtils.AspNetCore.ErrorHandler

Repository files navigation

PowerUtils.AspNetCore.ErrorHandler

Logo

Handler to standardize error responses

Tests Mutation tests

Quality Gate Status Coverage Reliability Rating Bugs

NuGet Nuget License: MIT

Support to

  • .NET 9.0
  • .NET 8.0
  • .NET 7.0
  • .NET 6.0
  • .NET 5.0

Dependencies

  • Microsoft.AspNetCore.App NuGet

How to use

Install NuGet package

This package is available through Nuget Packages: https://www.nuget.org/packages/PowerUtils.AspNetCore.ErrorHandler

Nuget

Install-Package PowerUtils.AspNetCore.ErrorHandler

.NET CLI

dotnet add package PowerUtils.AspNetCore.ErrorHandler

Configure

ErrorHandler configuration

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddErrorHandler();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseErrorHandler();
    }
}

PropertyNamingPolicy

Options:

  • Original: Do not format the property;
  • CamelCase: E.g. from ClientName to clientName Default value;
  • SnakeCase: E.g. from ClientName to client_name;
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddErrorHandler(options =>
        {
            options.PropertyNamingPolicy = PropertyNamingPolicy.SnakeCase;
        });
    }
}

ExceptionMappers

Exception mapping to status code and error codes

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddErrorHandler(options =>
        {
            options.ExceptionMapper<DuplicatedException>(exception => StatusCodes.Status409Conflict);

            options.ExceptionMapper<PropertyException>(exception => (400, exception.Property, exception.Code, exception.Message));

            options.ExceptionMapper<ModelStatesException>(exception => (
                exception.Status,
                exception.Errors.ToDictionary(
                    k => k.Key,
                    v => new ErrorDetails(v.Value, exception.Message)
                )));
        });
    }
}

IProblemFactory

How to create a custom error problem details for example in a controller

[ApiController]
[Route("home")]
public class HomeController : ControllerBase
{
    private readonly IProblemFactory _problemFactory;

    public ProblemFactoryController(IProblemFactory problemFactory)
        => _problemFactory = problemFactory;



    [HttpGet("call-1")]
    public IActionResult Call1()
        => _problemFactory.CreateProblemResult(
            detail: "detail",
            instance: "instance",
            statusCode: (int)HttpStatusCode.BadRequest,
            title: "title",
            type: "type",
            errors: new Dictionary<string, string>
            {
                ["Property1"] = new("Error1", "Message1"),
                ["Property2"] = new("Error2", "Message2"),
                ["Property3"] = new("Error3", "Message3"),
            });

    [HttpGet("call-2")]
    public IActionResult Call2()
        => new ObjectResult(_problemFactory.CreateProblem(
            detail: "detail",
            instance: "instance",
            statusCode: (int)HttpStatusCode.BadRequest,
            title: "title",
            type: "type",
            errors: new Dictionary<string, string>
            {
                ["Property1"] = new("Error1", "Message1"),
                ["Property2"] = new("Error2", "Message2"),
                ["Property3"] = new("Error3", "Message3"),
            }
        ));
}

Customize problem link and problem title

Exception mapping to status code and error codes

Add new custom status code
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<ApiBehaviorOptions>(options =>
        {
            options.ClientErrorMapping.Add(582, new()
            {
                Link = "CustomLink",
                Title = "CustomTitle"
            });
        });
    }
}
Change link and title for a specific status code

Add your customization after services.AddErrorHandler(); because it will override the defaults status codes

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddErrorHandler();
        services.Configure<ApiBehaviorOptions>(options =>
        {
            options.ClientErrorMapping[403].Link = "OverrideLink";
            options.ClientErrorMapping[403].Title = "OverrideTitle";
        });
    }
}

Contribution

If you have any questions, comments, or suggestions, please open an issue or create a pull request