ExceptionHandlingMiddleware now returns structured ProblemDetails responses for errors, including specific handling for InvalidOperationException (400 Bad Request) and general exceptions (500 Internal Server Error). Responses use "application/problem+json" content type and include trace IDs. ProblemDetails support is also registered in Program.cs.
54 lines
1.6 KiB
C#
54 lines
1.6 KiB
C#
using Microsoft.AspNetCore.Mvc;
|
|
|
|
namespace DbFirst.API.Middleware;
|
|
|
|
public class ExceptionHandlingMiddleware
|
|
{
|
|
private readonly RequestDelegate _next;
|
|
private readonly ILogger<ExceptionHandlingMiddleware> _logger;
|
|
|
|
public ExceptionHandlingMiddleware(RequestDelegate next, ILogger<ExceptionHandlingMiddleware> logger)
|
|
{
|
|
_next = next;
|
|
_logger = logger;
|
|
}
|
|
|
|
public async Task InvokeAsync(HttpContext context)
|
|
{
|
|
try
|
|
{
|
|
await _next(context);
|
|
}
|
|
catch (InvalidOperationException ex)
|
|
{
|
|
_logger.LogWarning(ex, "Domain validation error");
|
|
await WriteProblemAsync(context, StatusCodes.Status400BadRequest, "Eingabe ungültig", ex.Message);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Unhandled exception");
|
|
await WriteProblemAsync(context, StatusCodes.Status500InternalServerError, "Serverfehler", ex.Message);
|
|
}
|
|
}
|
|
|
|
private static async Task WriteProblemAsync(HttpContext context, int status, string title, string detail)
|
|
{
|
|
if (context.Response.HasStarted) return;
|
|
|
|
context.Response.Clear();
|
|
context.Response.StatusCode = status;
|
|
context.Response.ContentType = "application/problem+json";
|
|
|
|
var problem = new ProblemDetails
|
|
{
|
|
Type = $"https://tools.ietf.org/html/rfc9110#section-{(status == 400 ? "15.5.1" : "15.6.1")}",
|
|
Title = title,
|
|
Status = status,
|
|
Detail = detail,
|
|
Extensions = { ["traceId"] = context.TraceIdentifier }
|
|
};
|
|
|
|
await context.Response.WriteAsJsonAsync(problem);
|
|
}
|
|
}
|