Глобальная обработка исключений

Я использую в проекте глобальную обработку исключений. Проблема в том, что некоторые исключения не доходят до обработчика и обрабатываются раньше из-за чего я не могу подкорректировать response. Например, я делаю ошибку при запросе, где специально указываю пустое значению ключу или указываю слишком большое значение для переменной из-за чего происходит переполнение. После JsonSerializer при попытке сериализовать в DTO выдаёт, допустим, вот такое исключение: "The JSON value could not be converted to System.UInt16". Я ожидаю, что это исключение попадёт в метод HandleExceptionAsync(HttpContext context, Exception exception), но до этого метода ничего не доходит, исключение обрабатывается раньше и отсылается как есть. При это другие ексепшены он ловит, например, от FluentValidation или деление на ноль.

Код CustomExceptionHandlerMiddleware:

using System.Net;
using System.Text.Json;
using FluentValidation;
using Company.Application.Common.Exceptions;

namespace TransportPetrus.WebAPI.Middleware
{
    public class CustomExceptionHandlerMiddleware 
    {
        private readonly RequestDelegate _next;

        public CustomExceptionHandlerMiddleware(RequestDelegate next)
        {
            _next = next;

        }

        public async Task Invoke(HttpContext context)
        {
            
            try
            {
                await _next(context);
            }
            catch (Exception exception)
            {
                await HandleExceptionAsync(context, exception);
            }
        }

        private async Task HandleExceptionAsync(HttpContext context, Exception exception)
        {
            var code = HttpStatusCode.InternalServerError;
            var result = string.Empty;

            switch (exception)
            {
                case ValidationException validationException:
                    code = HttpStatusCode.BadRequest;
                    result = JsonSerializer.Serialize(validationException.Errors.Select(error => error.PropertyName + " - " + error.ErrorMessage));
                    break;
                case NotFoundException:
                    code = HttpStatusCode.NotFound;
                    break;
            }

            context.Response.ContentType = "application/json";
            context.Response.StatusCode = (int)code;

            if (result == string.Empty)
            {
                result = JsonSerializer.Serialize(new { error = exception.Message }); //тут я планирую подредактивровать response
            }

            await context.Response.WriteAsync(result);
        }
    }
}

Program.cs код

using Company.Application;
using Company.Application.Common.Mapping;
using Company.Persistence;
using Company.WebAPI.Middleware;
using System.Reflection;

namespace Company.WebAPI
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            builder.Services.AddPersistence(builder.Configuration);

            using (var scope = builder.Services.BuildServiceProvider().CreateScope())
            {
                var serviceProvider = scope.ServiceProvider;

                try
                {
                    var context = serviceProvider.GetRequiredService<CompanyDbContext>();
                    DbInitializer.Initialize(context);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
            }

            builder.Services.AddAutoMapper(config =>
            {
                config.AddProfile(new AssambleMappingProfile(Assembly.GetExecutingAssembly()));
                config.AddProfile(new AssambleMappingProfile(typeof(CompanyDbContext).Assembly));
            });

            builder.Services.AddCors(config =>
            {
                config.AddPolicy("AllowAll", policy =>
                {
                    policy.AllowAnyHeader();
                    policy.AllowAnyMethod();
                    policy.AllowAnyOrigin();
                });
            });

            builder.Services.AddApplication();
            builder.Services.AddControllers();
            builder.Services.AddEndpointsApiExplorer();

            var app = builder.Build();

            app.UseCustomExceptionHandler();
            app.UseRouting();
            app.UseHttpsRedirection();
            app.UseCors("AllowAll");
            app.UseAuthentication();
            app.UseAuthorization();
            app.MapControllers();
            app.Run();
        }
    }
}

Пример запроса Postman:

{
    "CargoType": "Какой-то тип груза",
    "ShippingPort" : "Какой-то порт",
    "ContainerType" : "Какой-то контейнер",
    "DeliveryPlace" : "Какое-то место доставки",
    "PackagingType" : "Какая-то упаковка",
    "CustomsClearance" : "Какой-то таможенное оформление",
    "TranshipmentPort" : "Какой-то порт перевалки",
    "DeliveryConditions" : "Какие-то условия доставки",
    "DeadlineProvidingCP" : "Какой-то срок предоставления кп",
    "CargoReadinessPeriod" : "Какая-то готовность груза",
    "RatePerContainer" : "12",
    "DollarExchangeRate" : "1",
    "RatePerTon" : "1",
    "WeightOnePiece" : "1",
    "LoadingPerContainerGross": "2222222", //Будет вызвано переполнение
    "LoadingPerContainerNet" : "3",
    "PlacesInContainer" : "2",
    "NumberOfContainers" : "2",
    "Note" : ""
}

Ответ Postman:

{
    "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "errors": {
        "createRequestTransportationRateDto": [
            "The createRequestTransportationRateDto field is required."
        ],
        "$.LoadingPerContainerGross": [
            "The JSON value could not be converted to System.UInt16. Path: $.LoadingPerContainerGross | LineNumber: 15 | BytePositionInLine: 41."
        ]
    },
    "traceId": "00-3415b33b737a06577c6dca7b2abb6239-339a2df72d7763eb-00"
}

Ответ я хочу отредактировать и убрать лишнее.


Ответы (0 шт):