refactor: to return the result according to the RFC 7807 standard and add a traceId
This commit is contained in:
@ -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));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user