Handler to standardize error responses
- .NET 9.0
- .NET 8.0
- .NET 7.0
- .NET 6.0
- .NET 5.0
- Microsoft.AspNetCore.App NuGet
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
ErrorHandler configuration
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddErrorHandler();
}
public void Configure(IApplicationBuilder app)
{
app.UseErrorHandler();
}
}
Options:
- Original: Do not format the property;
- CamelCase: E.g. from
ClientName
toclientName
Default value; - SnakeCase: E.g. from
ClientName
toclient_name
;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddErrorHandler(options =>
{
options.PropertyNamingPolicy = PropertyNamingPolicy.SnakeCase;
});
}
}
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)
)));
});
}
}
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"),
}
));
}
Exception mapping to status code and error codes
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.Configure<ApiBehaviorOptions>(options =>
{
options.ClientErrorMapping.Add(582, new()
{
Link = "CustomLink",
Title = "CustomTitle"
});
});
}
}
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";
});
}
}
If you have any questions, comments, or suggestions, please open an issue or create a pull request