Отключить обработку ошибок по умолчанию с оптимизацией CMS в ядре ASP.NET Core

Введение

При построении веб -приложения .NET он обычно использует комбинацию UseExceptionHandler и UseStatusCodePagesWithReExecute в вашем Startup.cs Чтобы обслуживать страницы ошибок, удобные для пользователя:

app.UseExceptionHandler("/errorhandler/500");
app.UseStatusCodePagesWithReExecute("/errorhandler/{0}");

Это работает плавно – даже для оптимизированных решений CMS. Тем не менее, мы недавно обнаружили предостережение, работая над проектом, включающим пользовательские конечные точки API. Оказывается, оптимизируется имеет свое собственное скрытое поведение в отношении обработки ошибок, и оно может молча мешать вашим тщательно настроенным трубопроводам.

 

Проблема: пользовательские ошибки для сегмента API

У нас был маршрут API, который намеренно Возвращает необработанные коды статуса HTTP (например, 401 несанкционированный) в зависимости от бизнес -логики. Ожидаемое поведение состояло в том, чтобы вернуть фактический код ответа HTTP, а не дружественную страницу ошибок HTML.

Однако один раз UseStatusCodePagesWithReExecute включено, даже конечные точки API, как /my/custom/api Поиск, и вы получите ответ HTML -ошибки, когда ваш API возвращает 401.

Итак, мы добавили условную логику:

app.UseWhen(
    context => !context.Request.Path.StartsWithSegments("/my/custom/api"),
    appBuilder =>
    {
        appBuilder.UseExceptionHandler("/errorhandler/500");
        appBuilder.UseStatusCodePagesWithReExecute("/errorhandler/{0}");
    });

Это работает –Пока вы не пойдете на производствоПолем

Сюрприз: оптимизируемые крючки в своем собственном промежуточном программном обеспечении

К нашему удивлению, наш API все еще возвращал страницу ошибок Optimizely в производстве. После некоторого копания мы обнаружили, что Оптимизируемо CMS автоматически регистрирует свое собственное исключение и обработку кода состояниянезависимо от того, что вы настраиваете.

Это происходит, когда вы звоните .AddCms()-конкретно, .AddCmsUI() Внутренне регистрирует следующую услугу:

services.AddStartupFilter();

Этот фильтр выглядит так:

public Action Configure(Action nextAction)
{
    return app =>
    {
        if (app.ApplicationServices.GetRequiredService().IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseStatusCodePagesWithReExecute("/Util/Errors/Error{0}");
            app.UseExceptionHandler("/Util/Errors/Error500");
        }

        nextAction(app);
    };
}

Итак, оптимизировать всегда провода в собственных обработчиках ошибок – после ваших.

Read more:  Вирусная земля будет совершенно темной из -за солнечного затмения 2 августа, это факт

Наше решение: удалить фильтр запуска

Там нет публичной конфигурации, чтобы отключить такое поведение. Класс есть internalпоэтому вы не можете переопределить или настроить его. Мы должны были самостоятельно удалить его из коллекции услуг:

var errorStartupFilterServiceDescriptor = services
    .FirstOrDefault(descriptor => descriptor.ImplementationType?.Name == "ErrorsStartupFilter");

if (errorStartupFilterServiceDescriptor != null)
{
    services.Remove(errorStartupFilterServiceDescriptor);
}

Делая это в начале ConfigureServicesВы предотвращаете инъекцию обработчиков ошибок Optimizely, снова предоставив вам полный контроль над трубопроводом.

Последние мысли

Это один из тех “Framework Magic vs. Control” Control “ ситуации. Его легко пропустить, потому что все, кажется, работает на местном уровне – до тех пор, пока производство не разоблачит конфликт.

Надеюсь, это экономит кого -то несколько часов отладки!

По теме

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.