Files
EndavaTask/EndavaTask/Middleware/ExceptionHandlingMiddleware.cs

73 lines
2.6 KiB
C#

using System.Text.Json;
using EndavaTask.Exceptions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
namespace EndavaTask.Middleware;
public class ExceptionHandlingMiddleware(RequestDelegate next, ILogger<ExceptionHandlingMiddleware> logger, IHostEnvironment environment)
{
public async Task InvokeAsync(HttpContext context)
{
try
{
await next(context);
}
catch (Exception exception)
{
logger.LogError(exception, "Unhandled exception while processing {Method} {Path}", context.Request.Method, context.Request.Path);
var details = BuildProblemDetails(context, exception);
context.Response.StatusCode = details.Status ?? StatusCodes.Status500InternalServerError;
context.Response.ContentType = "application/problem+json";
details.Extensions["traceId"] = context.TraceIdentifier;
var json = JsonSerializer.Serialize(details);
await context.Response.WriteAsync(json);
}
}
private ProblemDetails BuildProblemDetails(HttpContext context, Exception exception)
{
switch (exception)
{
case ApiValidationException validationException:
{
var modelState = new ModelStateDictionary();
foreach (var error in validationException.Errors)
{
foreach (var message in error.Value)
{
modelState.AddModelError(error.Key, message);
}
}
return new ValidationProblemDetails(modelState)
{
Status = StatusCodes.Status400BadRequest,
Title = "Validation failed",
Detail = "One or more validation errors occurred.",
Instance = context.Request.Path
};
}
case ApiNotFoundException:
return new ProblemDetails
{
Status = StatusCodes.Status404NotFound,
Title = "Resource not found",
Detail = exception.Message,
Instance = context.Request.Path
};
default:
return new ProblemDetails
{
Status = StatusCodes.Status500InternalServerError,
Title = "Unexpected server error",
Detail = environment.IsDevelopment() ? exception.Message : "An unexpected error occurred.",
Instance = context.Request.Path
};
}
}
}