autobus-api_old/AutobusApi.Api/Middlewares/GlobalExceptionHandlerMiddleware.cs

146 lines
5.6 KiB
C#

using AutobusApi.Application.Common.Exceptions;
using Microsoft.AspNetCore.Mvc;
namespace AutobusApi.Api.Middlewares;
public class GlobalExceptionHandlerMiddleware : IMiddleware
{
private readonly Dictionary<Type, Func<HttpContext, Exception, Task>> _exceptionHandlers;
public GlobalExceptionHandlerMiddleware()
{
// Register known exception types and handlers.
_exceptionHandlers = new()
{
{ typeof(ValidationException), HandleValidationException },
{ typeof(RegistrationException), HandleRegistrationException },
{ typeof(LoginException), HandleLoginException },
{ typeof(RenewAccessTokenException), HandleRenewAccessTokenException },
{ typeof(RevokeRefreshTokenException), HandleRevokeRefreshTokenException },
{ typeof(NotFoundException), HandleNotFoundException },
};
}
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
try
{
await next(context);
}
catch (Exception exception)
{
var exceptionType = exception.GetType();
if (_exceptionHandlers.ContainsKey(exceptionType))
{
await _exceptionHandlers[exceptionType].Invoke(context, exception);
return;
}
await HandleUnhandledExceptionException(context, exception);
}
}
private async Task HandleValidationException(HttpContext context, Exception exception)
{
var ex = (ValidationException) exception;
context.Response.StatusCode = StatusCodes.Status400BadRequest;
context.Response.ContentType = "application/problem+json";
await context.Response.WriteAsJsonAsync(new HttpValidationProblemDetails(ex.Errors)
{
Status = StatusCodes.Status400BadRequest,
Type = "https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.1",
Detail = "Check provided information."
});
}
private async Task HandleRegistrationException(HttpContext context, Exception exception)
{
context.Response.StatusCode = StatusCodes.Status400BadRequest;
context.Response.ContentType = "application/problem+json";
await context.Response.WriteAsJsonAsync(new ProblemDetails()
{
Status = StatusCodes.Status400BadRequest,
Type = "https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.1",
Title = "Registration failed.",
Detail = "Check your credentials."
});
}
private async Task HandleLoginException(HttpContext context, Exception exception)
{
context.Response.StatusCode = StatusCodes.Status400BadRequest;
context.Response.ContentType = "application/problem+json";
await context.Response.WriteAsJsonAsync(new ProblemDetails()
{
Status = StatusCodes.Status400BadRequest,
Type = "https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.1",
Title = "Login failed.",
Detail = "Provided email and/or password are invalid."
});
}
private async Task HandleRenewAccessTokenException(HttpContext context, Exception exception)
{
context.Response.StatusCode = StatusCodes.Status400BadRequest;
context.Response.ContentType = "application/problem+json";
await context.Response.WriteAsJsonAsync(new ProblemDetails()
{
Status = StatusCodes.Status400BadRequest,
Type = "https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.1",
Title = "Access token renewal failed.",
Detail = "Check validity of your refresh token."
});
}
private async Task HandleRevokeRefreshTokenException(HttpContext context, Exception exception)
{
context.Response.StatusCode = StatusCodes.Status400BadRequest;
context.Response.ContentType = "application/problem+json";
await context.Response.WriteAsJsonAsync(new ProblemDetails()
{
Status = StatusCodes.Status400BadRequest,
Type = "https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.1",
Title = "Refresh token revocation failed.",
Detail = "Check validity of your refresh token."
});
}
private async Task HandleNotFoundException(HttpContext context, Exception exception)
{
context.Response.StatusCode = StatusCodes.Status404NotFound;
context.Response.ContentType = "application/problem+json";
await context.Response.WriteAsJsonAsync(new ProblemDetails()
{
Status = StatusCodes.Status404NotFound,
Type = "https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.4",
// Title = "Refresh token revocation failed.",
// Detail = "Check validity of your refresh token."
});
}
private async Task HandleUnhandledExceptionException(HttpContext context, Exception exception)
{
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
context.Response.ContentType = "application/problem+json";
await context.Response.WriteAsJsonAsync(new ProblemDetails()
{
Status = StatusCodes.Status500InternalServerError,
Type = "https://datatracker.ietf.org/doc/html/rfc7231#section-6.6.1",
Title = "One or more internal server errors occured.",
Detail = "Report this error to service's support team.",
});
await Console.Error.WriteLineAsync(exception.Message);
await Console.Error.WriteLineAsync(exception.StackTrace);
}
}