refactor: to return the result according to the RFC 7807 standard and add a traceId

This commit is contained in:
2024-12-22 05:25:19 +03:00
parent f2e79e51f2
commit e4b942d062
10 changed files with 68 additions and 74 deletions

View File

@ -1,10 +1,13 @@
using FluentValidation;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Mirea.Api.DataAccess.Application.Common.Exceptions;
using Mirea.Api.Dto.Responses;
using Mirea.Api.Endpoint.Common.Exceptions;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Security;
using System.Text.Json;
using System.Threading.Tasks;
@ -27,50 +30,55 @@ public class CustomExceptionHandlerMiddleware(RequestDelegate next, ILogger<Cust
private Task HandleExceptionAsync(HttpContext context, Exception exception)
{
var code = StatusCodes.Status500InternalServerError;
var result = string.Empty;
var traceId = Activity.Current?.Id ?? context.TraceIdentifier;
var problemDetails = new ProblemDetails
{
Type = "https://tools.ietf.org/html/rfc9110#section-15.6",
Title = "An unexpected error occurred.",
Status = StatusCodes.Status500InternalServerError,
Detail = exception.Message,
Extensions = new Dictionary<string, object?>()
{
{ "traceId", traceId }
}
};
switch (exception)
{
case ValidationException validationException:
code = StatusCodes.Status400BadRequest;
result = JsonSerializer.Serialize(new ErrorResponse()
problemDetails.Status = StatusCodes.Status400BadRequest;
problemDetails.Type = "https://tools.ietf.org/html/rfc9110#section-15.5.1";
problemDetails.Title = "Validation errors occurred.";
problemDetails.Extensions = new Dictionary<string, object?>
{
Error = validationException.Message,
Code = code
});
{ "errors", validationException.Errors.Select(e => e.ErrorMessage).ToArray() },
{ "traceId", traceId }
};
break;
case NotFoundException:
code = StatusCodes.Status404NotFound;
problemDetails.Status = StatusCodes.Status404NotFound;
problemDetails.Type = "https://tools.ietf.org/html/rfc9110#section-15.5.4";
problemDetails.Title = "Resource not found.";
break;
case ControllerArgumentException:
code = StatusCodes.Status400BadRequest;
problemDetails.Status = StatusCodes.Status400BadRequest;
problemDetails.Type = "https://tools.ietf.org/html/rfc9110#section-15.5.1";
problemDetails.Title = "Invalid arguments provided.";
break;
case SecurityException:
code = StatusCodes.Status401Unauthorized;
problemDetails.Status = StatusCodes.Status401Unauthorized;
problemDetails.Type = "https://tools.ietf.org/html/rfc9110#section-15.5.2";
problemDetails.Title = "Unauthorized access.";
break;
}
context.Response.ContentType = "application/json";
context.Response.StatusCode = code;
if (!string.IsNullOrEmpty(result))
return context.Response.WriteAsync(result);
string error;
if (code == StatusCodes.Status500InternalServerError)
{
error = "Internal Server Error";
if (problemDetails.Status == StatusCodes.Status500InternalServerError)
logger.LogError(exception, "Internal server error when processing the request");
}
else
error = exception.Message;
result = JsonSerializer.Serialize(new ErrorResponse()
{
Error = error,
Code = code
});
context.Response.ContentType = "application/json";
context.Response.StatusCode = problemDetails.Status.Value;
return context.Response.WriteAsync(result);
return context.Response.WriteAsync(JsonSerializer.Serialize(problemDetails));
}
}