From 0700241ed05deb44e030dc91e25e0e47b56e65f5 Mon Sep 17 00:00:00 2001 From: Enzo Thomazi Lucas Date: Fri, 1 Dec 2023 00:46:08 -0300 Subject: [PATCH] feat: Implementing error handling middleware --- .../ApplicationBuilderExtensions.cs | 5 +- .../Middlewares/ErrorHandlingMiddleware.cs | 87 +++++++++++++++++-- 2 files changed, 85 insertions(+), 7 deletions(-) diff --git a/src/shared/Example.EventDriven.DependencyInjection/ApplicationBuilderExtensions.cs b/src/shared/Example.EventDriven.DependencyInjection/ApplicationBuilderExtensions.cs index a147747..33eab96 100644 --- a/src/shared/Example.EventDriven.DependencyInjection/ApplicationBuilderExtensions.cs +++ b/src/shared/Example.EventDriven.DependencyInjection/ApplicationBuilderExtensions.cs @@ -1,4 +1,5 @@ -using Example.EventDriven.DependencyInjection.Swagger; +using Example.EventDriven.DependencyInjection.Middlewares; +using Example.EventDriven.DependencyInjection.Swagger; using Microsoft.AspNetCore.Builder; using System.Diagnostics.CodeAnalysis; @@ -17,6 +18,8 @@ public static IApplicationBuilder UseApiDependencyInjection(this IApplicationBui app.UseSwaggerConfiguration(); + app.UseMiddleware(); + return app; } diff --git a/src/shared/Example.EventDriven.DependencyInjection/Middlewares/ErrorHandlingMiddleware.cs b/src/shared/Example.EventDriven.DependencyInjection/Middlewares/ErrorHandlingMiddleware.cs index a7c7562..394c06b 100644 --- a/src/shared/Example.EventDriven.DependencyInjection/Middlewares/ErrorHandlingMiddleware.cs +++ b/src/shared/Example.EventDriven.DependencyInjection/Middlewares/ErrorHandlingMiddleware.cs @@ -1,13 +1,88 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Example.EventDriven.Domain.Exceptions; +using Example.EventDriven.Domain.Gateways.Logger; +using FluentValidation; +using Microsoft.AspNetCore.Http; +using Newtonsoft.Json; +using System.Net; namespace Example.EventDriven.DependencyInjection.Middlewares { - public class ErrorHandlingMiddleware + public sealed class ErrorHandlingMiddleware { + private readonly ILoggerManager _logger; + private readonly RequestDelegate _next; + public ErrorHandlingMiddleware(ILoggerManager logger, RequestDelegate next) + { + _logger = logger; + _next = next; + } + + public async Task InvokeAsync(HttpContext context) + { + try + { + await _next(context); + } + catch (BusinessException ex) + { + _logger.Log("Business error caught by middleware", LoggerManagerSeverity.WARNING, ("exception", ex)); + + await HandleExceptionAsync(context, ex); + } + catch (ValidationException ex) + { + _logger.Log("Validation error caught by middleware", LoggerManagerSeverity.WARNING, ("exception", ex)); + + await HandleExceptionAsync(context, ex); + } + catch (Exception ex) + { + _logger.LogException("Unexpected error caught by middleware", LoggerManagerSeverity.ERROR, ex); + + await HandleExceptionAsync(context); + } + } + + private static Task HandleExceptionAsync(HttpContext context, BusinessException exception) + { + var code = HttpStatusCode.BadRequest; + + var result = JsonConvert.SerializeObject(new { Errors = new string[1] { exception.Message } }); + + return ErrorResponse(context, result, code); + } + + private static Task HandleExceptionAsync(HttpContext context, ValidationException exception) + { + var code = HttpStatusCode.BadRequest; + + var result = JsonConvert.SerializeObject(new { Errors = exception.Errors.Select(e => e.ErrorMessage).ToArray() }); + + return ErrorResponse(context, result, code); + } + + private static Task HandleExceptionAsync(HttpContext context) + { + var code = HttpStatusCode.InternalServerError; + + return ErrorResponse(context, code); + } + + private static Task ErrorResponse(HttpContext context, HttpStatusCode code) + { + var result = JsonConvert.SerializeObject(new { Errors = new string[1] { "UnexpectedError" } }); + + return ErrorResponse(context, result, code); + } + + private static Task ErrorResponse(HttpContext context, string result, HttpStatusCode code) + { + context.Response.ContentType = "application/json"; + + context.Response.StatusCode = (int)code; + + return context.Response.WriteAsync(result); + } } }