Middleware to handle Exceptions Globally on .NET


First, we add the APIExceptions class:

namespace RestAPI.Errors

{

    public class ApiException(int statusCode, string message, string? details)

    {

        public int StatusCode { get; set; } = statusCode;

        public string Message { get; set; } = message;

        public string? Details { get; set; } = details;

    }

}



Next, we generate the middleware code:


using System.Net;
using System.Text.Json;

namespace RestAPI.Middleware
{
    public class ExceptionMiddleware(RequestDelegate next, 
        ILogger<ExceptionMiddleware> logger, IHostEnvironment environment)
    {
        public async Task InvokeAsync(HttpContext context)
        {
            try
            {
                await next(context);
            }
            catch (Exception ex)
            {

                logger.LogError(ex, "{message}", ex.Message);
                context.Response.ContentType = "application/json";
                context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;

                var response = environment.IsDevelopment()
                    ? new Errors.ApiException(context.Response.StatusCode, ex.Message, ex.StackTrace?.ToString())
                    : new Errors.ApiException(context.Response.StatusCode, ex.Message, "Internal Server Error");

                var options = new JsonSerializerOptions
                {
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
                };

                var json = JsonSerializer.Serialize(response, options);

                await context.Response.WriteAsync(json);
            }
        }
    }
}


Finally, we add it into the .NET request-response pipeline:

var app = builder.Build();

// Configure the HTTP request pipeline.
app.UseMiddleware<ExceptionMiddleware>();


Comments

Popular Posts