Improve exception handling and validation responses

Updated `ExceptionHandlingMiddleware` to enhance error handling:
- Added `Microsoft.AspNetCore.Mvc` and `System.Text.Json` for structured JSON responses.
- Made `message` nullable to handle cases without explicit messages.
- Refactored `ValidationException` handling:
  - Changed HTTP status code from 422 to 400.
  - Grouped validation errors by property and returned them in a `ValidationProblemDetails` object.
- Conditionally wrote `message` to the response only if not null.
- Improved structure and clarity of validation error responses.
This commit is contained in:
tekh 2025-12-03 15:35:06 +01:00
parent 459cc1cb9a
commit bf98efd3a3

View File

@ -1,5 +1,6 @@
using DigitalData.Core.Exceptions; using DigitalData.Core.Exceptions;
using FluentValidation; using FluentValidation;
using Microsoft.AspNetCore.Mvc;
using ReC.Application.Common.Exceptions; using ReC.Application.Common.Exceptions;
using System.Net; using System.Net;
using System.Text.Json; using System.Text.Json;
@ -57,7 +58,7 @@ public class ExceptionHandlingMiddleware
{ {
context.Response.ContentType = "application/json"; context.Response.ContentType = "application/json";
string message; string? message = null;
switch (exception) switch (exception)
{ {
@ -67,8 +68,20 @@ public class ExceptionHandlingMiddleware
break; break;
case ValidationException validationEx: case ValidationException validationEx:
context.Response.StatusCode = (int)HttpStatusCode.UnprocessableEntity; context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
message = "Validation failed: " + string.Join("; ", validationEx.Errors.Select(e => e.ErrorMessage));
var errors = validationEx.Errors
.GroupBy(e => e.PropertyName, e => e.ErrorMessage)
.ToDictionary(failureGroup => failureGroup.Key, failureGroup => failureGroup.ToArray());
await context.Response.WriteAsJsonAsync(new ValidationProblemDetails()
{
Title = "Validation failed",
Errors = validationEx.Errors
.GroupBy(e => e.PropertyName, e => e.ErrorMessage)
.ToDictionary(failureGroup => failureGroup.Key, failureGroup => failureGroup.ToArray()),
});
break; break;
case NotFoundException notFoundEx: case NotFoundException notFoundEx:
@ -88,6 +101,7 @@ public class ExceptionHandlingMiddleware
break; break;
} }
if (message is not null)
await context.Response.WriteAsync(JsonSerializer.Serialize(new await context.Response.WriteAsync(JsonSerializer.Serialize(new
{ {
message message