Add exception handling middleware

Implement global exception handling to provide consistent error responses.
Registes custom exceptions with corresponding HTTP status codes and descriptions.
This commit is contained in:
martinshoob 2025-08-11 18:36:12 +02:00
parent 1906d0de0d
commit 7bf7f23925
3 changed files with 16 additions and 7 deletions

View file

@ -19,6 +19,7 @@ public class UserProfileController : ControllerBase
_userProfileService = userProfileService;
}
[HttpPut]
public UserProfileGet PutUserProfile([FromBody] UserProfilePut userProfile)
{
throw new ApplicationException();

View file

@ -1,8 +1,9 @@
using System.Net;
using Microsoft.AspNetCore.Http.HttpResults;
namespace DrinkRateAPI.Exceptions;
public record ExceptionResponse(HttpStatusCode StatusCode, string Description);
public record ExceptionResponse(int StatusCode, string Description);
public class ExceptionHandlingMiddleware
{
@ -32,16 +33,20 @@ public class ExceptionHandlingMiddleware
_logger.LogError(exception, "An unexpected error occurred.");
ExceptionResponse response = exception switch
var response = exception switch
{
ApplicationException _ => new ExceptionResponse(HttpStatusCode.BadRequest, "Application exception occurred."),
KeyNotFoundException _ => new ExceptionResponse(HttpStatusCode.NotFound, "The request key not found."),
UnauthorizedAccessException _ => new ExceptionResponse(HttpStatusCode.Unauthorized, "Unauthorized."),
_ => new ExceptionResponse(HttpStatusCode.InternalServerError, "Internal server error. Please retry later.")
BadRequestException _ => new ExceptionResponse(StatusCodes.Status400BadRequest, "Application exception occurred."),
NotFoundException _ => new ExceptionResponse(StatusCodes.Status404NotFound, "The request key not found."),
UnauthenticatedException _ => new ExceptionResponse(StatusCodes.Status401Unauthorized, "Unauthorized."),
PaymentRequiredException _ => new ExceptionResponse(StatusCodes.Status402PaymentRequired, "Payment required."),
ForbiddenException _ => new ExceptionResponse(StatusCodes.Status403Forbidden, "Forbidden."),
IamATeapotException _ => new ExceptionResponse(StatusCodes.Status418ImATeapot, "I am a teapot."),
UnavailableForLagalReasonsException _ => new ExceptionResponse(StatusCodes.Status451UnavailableForLegalReasons, "Unavailable for legal reasons."),
_ => new ExceptionResponse(StatusCodes.Status500InternalServerError, "Internal server error. Please retry later.")
};
context.Response.ContentType = "application/json";
context.Response.StatusCode = (int)response.StatusCode;
context.Response.StatusCode = response.StatusCode;
await context.Response.WriteAsJsonAsync(response);
}
}

View file

@ -1,6 +1,7 @@
using DrinkRateAPI.AuthorizationPolicies;
using DrinkRateAPI.Contexts;
using DrinkRateAPI.DbEntities;
using DrinkRateAPI.Exceptions;
using DrinkRateAPI.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
@ -70,6 +71,8 @@ if (app.Environment.IsDevelopment())
app.MapIdentityApi<DbApplicationUser>();
app.UseMiddleware<ExceptionHandlingMiddleware>();
app.UseHttpsRedirection();
app.UseAuthorization();