UtilKit.ExceptionHandler
1.0.0
See the version list below for details.
dotnet add package UtilKit.ExceptionHandler --version 1.0.0
NuGet\Install-Package UtilKit.ExceptionHandler -Version 1.0.0
<PackageReference Include="UtilKit.ExceptionHandler" Version="1.0.0" />
<PackageVersion Include="UtilKit.ExceptionHandler" Version="1.0.0" />
<PackageReference Include="UtilKit.ExceptionHandler" />
paket add UtilKit.ExceptionHandler --version 1.0.0
#r "nuget: UtilKit.ExceptionHandler, 1.0.0"
#:package UtilKit.ExceptionHandler@1.0.0
#addin nuget:?package=UtilKit.ExceptionHandler&version=1.0.0
#tool nuget:?package=UtilKit.ExceptionHandler&version=1.0.0
UtilKit.ExceptionHandler
A global exception handling middleware for .NET APIs. Catches unhandled exceptions, logs them, and returns a clean JSON error response. Never leaks stack traces or internal details to clients.
Install
dotnet add package UtilKit.ExceptionHandler
Quick Start
// Program.cs
app.UseUtilKitExceptionHandler();
That's it. Any unhandled exception now returns:
HTTP 500:
{
"message": "An unexpected error occurred"
}
No stack trace. No internal details. Safe for production.
Configuration
Custom error message
app.UseUtilKitExceptionHandler(options =>
{
options.DefaultMessage = "Something went wrong. Please try again.";
options.DefaultStatusCode = 500;
});
Development mode (show exception details)
if (app.Environment.IsDevelopment())
{
app.UseUtilKitExceptionHandler(options =>
{
options.DefaultMessage = "An error occurred";
options.IncludeExceptionType = true;
options.IncludeStackTrace = true;
});
}
else
{
app.UseUtilKitExceptionHandler();
}
Development response:
{
"message": "An error occurred",
"type": "NullReferenceException",
"stackTrace": "at MyApp.Services..."
}
Production response:
{
"message": "An error occurred"
}
With ExceptionHandlerOptions object
app.UseUtilKitExceptionHandler(new ExceptionHandlerOptions
{
DefaultMessage = "Server error",
DefaultStatusCode = 500,
IncludeExceptionType = false,
IncludeStackTrace = false
});
Options
| Option | Type | Default | Description |
|---|---|---|---|
| DefaultMessage | string | "An unexpected error occurred" | Error message returned to client |
| DefaultStatusCode | int | 500 | HTTP status code |
| IncludeExceptionType | bool | false | Include exception class name in response |
| IncludeStackTrace | bool | false | Include stack trace in response |
⚠️ Never enable
IncludeStackTracein production. Stack traces expose internal code structure and are a security risk.
What it does
- Wraps your entire request pipeline in a try-catch
- If any exception is thrown and not handled:
- Logs the full exception (with stack trace) via
ILogger - Returns a clean JSON response to the client
- Never exposes internal details in production
- Logs the full exception (with stack trace) via
Exception Mapping
Use built-in defaults (one line)
app.UseUtilKitExceptionHandler(options =>
{
options.UseDefaultMappings();
});
Default mappings:
| Exception | HTTP Code | Message |
|---|---|---|
| NotFoundException | 404 | Uses exception message |
| ValidationException | 400 | Uses exception message |
| BadRequestException | 400 | Uses exception message |
| UnauthorizedException | 401 | Uses exception message |
| ForbiddenException | 403 | Uses exception message |
| ConflictException | 409 | Uses exception message |
| BusinessException | 422 | Uses exception message |
| TooManyRequestsException | 429 | Uses exception message |
| DatabaseException | 500 | "A database error occurred" (hides DB details) |
| ServiceUnavailableException | 503 | Uses exception message |
| Unmapped exceptions | 500 | "An unexpected error occurred" |
Custom mapping
app.UseUtilKitExceptionHandler(options =>
{
options.UseDefaultMappings();
options.Map<MyCustomException>(418, "I'm a teapot");
options.Map<PaymentException>(402); // uses exception message
});
Throw in your code
// Returns 404 with message
throw new NotFoundException("User with ID 123 not found");
// Returns 409 with message
throw new ConflictException("Email already registered");
// Returns 500 with fixed message (hides DB details)
throw new DatabaseException("Connection timeout", sqlException);
Placement
Add it first in the middleware pipeline — before everything else:
var app = builder.Build();
app.UseUtilKitExceptionHandler(); // First!
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
Disclaimer
This package is provided "as is" without warranty of any kind. The author(s) are not responsible for any damages, data loss, security breaches, or issues arising from the use of this package. It is the consumer's responsibility to:
- Test thoroughly in their environment before production use
- Review exception messages to ensure no sensitive data is exposed
- Never enable
IncludeStackTracein production - Implement additional security measures as needed for their application
Use at your own risk.
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. 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 was computed. 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 was computed. 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 was computed. 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 was computed. 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. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- Microsoft.AspNetCore.Http.Abstractions (>= 2.2.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 6.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 6.0.0)
- System.Text.Json (>= 6.0.11)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.