UtilKit.ExceptionHandler 1.1.0

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

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;
        options.IncludeInnerException = true;
    });
}
else
{
    app.UseUtilKitExceptionHandler();
}

Development response:

{
  "message": "An error occurred",
  "type": "NullReferenceException",
  "stackTrace": "at MyApp.Services...",
  "innerException": {
    "message": "Timeout expired...",
    "type": "SqlException"
  }
}

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
IncludeInnerException bool false Include inner exception message and type in response

⚠️ Never enable IncludeStackTrace in production. Stack traces expose internal code structure and are a security risk.

What it does

  1. Wraps your entire request pipeline in a try-catch
  2. 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

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 IncludeStackTrace in production
  • Implement additional security measures as needed for their application

Use at your own risk.

License

MIT

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.0 95 6/1/2026
1.0.0 99 4/21/2026