Skip to content

IExceptionHandler for exception handler middleware #46280

@Tratcher

Description

@Tratcher

Background and Motivation

The exception handling middleware is designed to take unexpected, unhandled exceptions, log them, and render a customizable response for the client. This is a last ditch effort to produce something human readable, otherwise the response will receive an empty 500. This is not intended for known cases or control flow. Expected exceptions should be handled at the individual call sites.

Ask: Some exceptions like database exceptions could happen in many places and having to handle those in each place requires a lot of redundant code. How can handling of known exceptions be centralized?

Proposed API

The IExceptionHandler is a new interface that can have multiple instances registered with DI. The existing exception handling middleware will resolve these and loop through them until something matches. If none match, a higher level log (warning?) will be written. Exception handlers are not run if the response has already started. The existing IDeveloperPageExceptionFilter is used similarly with the developer exception page.

Assembly: Microsoft.AspNetCore.Diagnostics.Abstractions

Microsoft.Extensions.DependencyInjection;

public static class ExceptionHandlerServiceCollectionExtensions
{
+  public static IServiceCollection AddExceptionHandler<T>(this IServiceCollection services) where T is IExceptionHandler;
}

namespace Microsoft.AspNetCore.Diagnostics;

+ public interface IExceptionHandler
+ {
+    ValueTask<bool> TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken);
+ }

Usage Examples

services.AddExceptionHandler<DBExceptionHandler>();

public class DBExceptionHandler : IExceptionHandler
{
  ValueTask<bool> TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken)
  {
    if (exception is DBException) ...
  };
}

Risks

We don't want to encourage developers to use exceptions as normal control flow, it's extremely in-efficient and poor design. We should document that expectation and avoid using this capability in our own components.

This should not be confused with the MVC IExceptionFilter.
https://learn.microsoft.com/en-us/dotnet/api/system.web.mvc.iexceptionfilter

Metadata

Metadata

Assignees

Labels

api-approvedAPI was approved in API review, it can be implementedarea-middlewareIncludes: URL rewrite, redirect, response cache/compression, session, and other general middlewaresfeature-diagnosticsDiagnostic middleware and pages (except EF diagnostics)

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions