Microsoft’s November launch of .NET 8 introduced every kind of nice new options. One of many good enhancements launched in ASP.NET Core 8 is IExceptionHandler, an interface that makes it simpler to deal with exceptions gracefully in ASP.NET Core internet functions.
Error dealing with has a protracted historical past in programming languages and frameworks. IExceptionHandler simplifies error dealing with by offering a callback and a central location for dealing with identified exceptions. On this article we’ll talk about how you should utilize IExceptionHandler in your ASP.NET Core 8 functions and current significant error responses to the person.
To make use of the code examples offered on this article, it’s best to have Visible Studio 2022 put in in your system. When you don’t have already got a duplicate, you may obtain Visible Studio 2022 right here.
Create an ASP.NET Core Internet API venture in Visible Studio 2022
To create an ASP.NET Core 8 Internet API venture in Visible Studio 2022, comply with the steps outlined under.
- Launch the Visible Studio 2022 IDE.
- Click on on “Create new venture.”
- Within the “Create new venture” window, choose “ASP.NET Core Internet API” from the record of templates displayed.
- Click on Subsequent.
- Within the “Configure your new venture” window, specify the title and site for the brand new venture.
- Optionally verify the “Place answer and venture in the identical listing” verify field, relying in your preferences.
- Click on Subsequent.
- Within the “Further Data” window proven subsequent, choose “.NET 8.0 (Lengthy Time period Help)” because the framework model, and be sure that the “Use controllers” field is unchecked. We’ll be utilizing minimal APIs on this venture.
- Elsewhere within the “Further Data” window, depart the “Authentication Sort” set to “None” (the default) and ensure the verify containers “Allow Open API Help,” “Configure for HTTPS,” and “Allow Docker” stay unchecked. We received’t be utilizing any of these options right here.
- Click on Create.
We’ll use this ASP.NET Core Internet API venture to work with the IExceptionHandler interface within the sections under.
Why do we want an exception handler?
In ASP.NET Core, an exception handler is a element that may deal with exceptions globally in an software. It could actually catch all unhandled exceptions after which generate acceptable error responses.
An exception handler may help implement a centralized error-handling mechanism, permitting your functions to fail gracefully. This may allow you to make sure that all exceptions are dealt with, errors are appropriately logged and processed, and significant error responses are generated and offered to the person.
Allow us to perceive this with an instance. Take into account the next code.
utilizing Microsoft.AspNetCore.Diagnostics; utilizing Microsoft.AspNetCore.Mvc; utilizing System.ComponentModel.DataAnnotations; utilizing System.Web; var builder = WebApplication.CreateBuilder(args); var app = builder.Construct(); app.UseExceptionHandler(decide => { }); app.MapGet("/GenerateError", () => { Â Â Â throw new NotImplementedException(); }); app.Run();
While you execute the applying and hit the /GenerateError endpoint, the response displayed in your internet browser will seem as proven under.
Determine 1: Response generated with out utilizing exception handlers.
Observe that the error response just isn’t formatted and it’s fairly tough to learn and perceive the error metadata from this response.
Introducing the IExceptionHandler interface
Exception dealing with has been utilized in programming languages for many years to deal with run-time errors in functions. ASP.NET Core 8 improves exception dealing with considerably with the introduction of the IExceptionHandler interface. You’ll be able to create a central class for exception dealing with in ASP.NET Core 8 by implementing the IExceptionHandler interface.
The IExceptionHandler interface appears like this:
public interface IExceptionHandler { Â Â Â ValueTask<bool> TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken); }
The IExceptionHandler interface accommodates the declaration of the TryHandleAsync technique. This technique accepts three parameters: an occasion of kind HttpContext, an Exception, and a CancellationToken. It returns ValueTask<bool> to point if the exception was dealt with efficiently or not.
While you implement the TryHandleAsync technique in your class that extends the IExceptionHandler interface, you could return a boolean worth from this technique. You need to return true if the exception was dealt with or false in any other case.
Create a customized exception handler in ASP.NET Core
To implement the IExceptionHandler interface, create a brand new class named GlobalExceptionHandler in a file of the identical title with a .cs extension. And enter the next code in there.
public class GlobalExceptionHandler(IHostEnvironment hostEnvironment, ILogger<GlobalExceptionHandler> logger) Â Â Â : IExceptionHandler { Â Â Â public async ValueTask<bool> TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken) Â Â Â { Â Â Â Â Â Â Â return true; Â Â Â } }
Your customized error dealing with logic ought to reside within the TryHandleAsync technique. The next code snippet reveals how one can deal with exceptions that happen in your software asynchronously.
non-public const string ExceptionMessage = "An unhandled exception has occurred whereas executing the request.";
public async ValueTask<bool> TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken)
{
   logger.LogError(exception, exception is Exception ? exception.Message : ExceptionMessage);
   var problemDetails = CreateProblemDetails(httpContext, exception);
   await httpContext.Response.WriteAsJsonAsync(problemDetails, cancellationToken);
   return true;
}
We’ll now reap the benefits of the open supply ProblemDetails middleware to generate constant, structured, machine-readable error messages. The CreateProblemDetails technique returns an occasion of ProblemDetails containing the error metadata, as proven within the code snippet given under.
non-public ProblemDetails CreateProblemDetails(in HttpContext httpContext, in Exception exception)
{
   httpContext.Response.ContentType = “software/json”;
   change (exception)
   {
       case NotImplementedException notImplementedException:
           httpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;              Â
           break;
       default:
           httpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;              Â
           break;
   }
   return new ProblemDetails
   {
       Standing = (int)httpContext.Response.StatusCode,
       Sort = exception.GetType().Identify,
       Title = “An sudden error occurred”,
       Element = exception.Message,
       Occasion = $”{httpContext.Request.Methodology} {httpContext.Request.Path}”
   };
}
Full supply code of our customized exception handler
The next code itemizing includes the whole supply code of the GlobalExceptionHandler class.
public class GlobalExceptionHandler(IHostEnvironment hostEnvironment, ILogger<GlobalExceptionHandler> logger)
   : IExceptionHandler
{
   non-public const string ExceptionMessage = “An unhandled exception has occurred whereas executing the request.”;
   public async ValueTask<bool> TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken)
   {
       logger.LogError(exception, exception is Exception ? exception.Message : ExceptionMessage);
       var problemDetails = CreateProblemDetails(httpContext, exception);
       await httpContext.Response.WriteAsJsonAsync(problemDetails, cancellationToken);
       return true;
   }
   non-public ProblemDetails CreateProblemDetails(in HttpContext httpContext, in Exception exception)
   {
       httpContext.Response.ContentType = “software/json”;
       change (exception)
       {
           case NotImplementedException notImplementedException:
               httpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;              Â
               break;
           default:
               httpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;              Â
               break;
       }
       return new ProblemDetails
       {
           Standing = (int)httpContext.Response.StatusCode,
           Sort = exception.GetType().Identify,
           Title = “An sudden error occurred”,
           Element = exception.Message,
           Occasion = $”{httpContext.Request.Methodology} {httpContext.Request.Path}”
       };
   }
}
Register the exception handler with the request processing pipeline
Now that our customized exception handler is prepared, we have to register it with the request processing pipeline to begin utilizing it in our software. You’ll be able to register the exception handler by together with the next line of code within the Program.cs file.
builder.Companies.AddExceptionHandler<GlobalExceptionHandler>();
Allow us to now create an error dealing with endpoint in Program.cs. When invoked this endpoint will show a user-friendly error response as specified within the configured error handler. To create an error dealing with endpoint, enter the next code within the Program.cs file.
app.MapGet("/GenerateError", () =>
{
   throw new ValidationException();
});
The decision to the UseExceptionHandler() technique configures the request processing pipeline in ASP.NET Core to deal with exceptions utilizing our middleware.
app.UseExceptionHandler(decide => { });
Now if you execute the applying and hit the /GenerateError endpoint, the response displayed within the internet browser will seem as under. A lot better!
Determine 2: Error response generated utilizing an error handler.
It’s all the time advisable to implement your individual customized exception dealing with in your software. This ensures not solely that the exception dealing with logic meets your necessities, but in addition that the error responses are generated in your required format. Naturally, rolling your individual exception handler additionally provides you rather more granular management over the exception dealing with mechanism.
Copyright © 2024 IDG Communications, Inc.