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",
});
}
}