130 lines
4.9 KiB
C#
130 lines
4.9 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 },
|
|
};
|
|
}
|
|
|
|
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 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.StackTrace);
|
|
}
|
|
}
|