#nullable enable using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using FluentValidation; using Microsoft.AspNetCore.Diagnostics; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; namespace _0_Framework.Exceptions.Handler; public class CustomExceptionHandler : IExceptionHandler { private readonly ILogger _logger; public CustomExceptionHandler(ILogger logger) { _logger = logger; } public async ValueTask TryHandleAsync(HttpContext context, Exception exception, CancellationToken cancellationToken) { _logger.LogError(exception, "Error Message: {exceptionMessage}, Type: {exceptionType}, Time: {time}, Path: {path}, TraceId: {traceId}", exception.Message, exception.GetType().FullName, DateTime.UtcNow, context.Request.Path, context.TraceIdentifier); (string Detail, string Title, int StatusCode, Dictionary? Extra) details = exception switch { ValidationException validationException => ( validationException.Errors.FirstOrDefault()?.ErrorMessage ?? "One or more validation errors occurred.", "Validation Error", context.Response.StatusCode = StatusCodes.Status400BadRequest, null ), InternalServerException => ( exception.Message, exception.GetType().Name, context.Response.StatusCode = StatusCodes.Status500InternalServerError, null ), BadRequestException bre => ( exception.Message, exception.GetType().Name, context.Response.StatusCode = StatusCodes.Status400BadRequest, bre.Extra ), NotFoundException => ( exception.Message, exception.GetType().Name, context.Response.StatusCode = StatusCodes.Status404NotFound, null ), UnAuthorizeException => ( exception.Message, exception.GetType().Name, context.Response.StatusCode = StatusCodes.Status401Unauthorized, null ), _ => ( exception.Message, exception.GetType().Name, context.Response.StatusCode = StatusCodes.Status500InternalServerError, null ) }; var problemDetails = new ProblemDetails { Title = details.Title, Detail = details.Detail, Status = details.StatusCode, Instance = context.Request.Path, Extensions = details.Extra ?? new Dictionary() }; problemDetails.Extensions.Add("traceId", context.TraceIdentifier); await context.Response.WriteAsJsonAsync(problemDetails, cancellationToken: cancellationToken); return true; } }