using System.ComponentModel.DataAnnotations; using System.Net; using Galaeth.ApiServer.Constants; using Galaeth.ApiServer.Models.Common; using Galaeth.Core.Constants; using Galaeth.Core.Exceptions; namespace Galaeth.ApiServer.Middleware; /// /// Handle exceptions caught in a request. /// public class ExceptionMiddleware { private readonly RequestDelegate _next; private readonly ILogger _logger; /// /// Initializes a new instance of the class. /// /// Instance of . /// Instance of . public ExceptionMiddleware( RequestDelegate next, ILogger logger) { _next = next; _logger = logger; } /// /// Invoke middleware. /// /// Instance of . public async Task InvokeAsync(HttpContext httpContext) { try { await _next(httpContext); } catch (ServiceException exception) { await HandleServiceExceptionAsync(httpContext, exception); } catch (ValidationException exception) { await HandleValidationExceptionAsync(httpContext, exception); } catch (Exception exception) { _logger.LogError( "Unhandled Exception: {path} using {method}: {exception}", httpContext.Request.Path, httpContext.Request.Method, exception); await HandleOtherExceptionAsync(httpContext); } } /// /// Api exception. /// /// Instance of . /// Instance of . private static async Task HandleServiceExceptionAsync(HttpContext context, ServiceException exception) { context.Response.ContentType = "application/json"; context.Response.StatusCode = (int)exception.HttpStatusCode; await context.Response.WriteAsJsonAsync(new ErrorResultModel { Error = exception.ErrorCode, Message = exception.ErrorMessage, }); } /// /// Validation failed. /// /// Instance of . /// Instance of . private static async Task HandleValidationExceptionAsync(HttpContext context, ValidationException exception) { context.Response.ContentType = "application/json"; context.Response.StatusCode = StatusCodes.Status422UnprocessableEntity; await context.Response.WriteAsJsonAsync(new ErrorResultModel { Error = CoreErrorCodes.ValidationError, Message = exception.Message, }); } /// /// Unexpected exception. /// /// Instance of . private static async Task HandleOtherExceptionAsync(HttpContext context) { context.Response.ContentType = "application/json"; context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; await context.Response.WriteAsJsonAsync(new ErrorResultModel() { Success = false, Error = ApiErrorCodes.UnknownError, Message = "Something went wrong. Try again later", }); } }