Работал ли с Exception Filter в ASP.NET Core?

«Работал ли с Exception Filter в ASP.NET Core?» — вопрос из категории ASP.NET Core, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, работал. В контексте ASP.NET Core Exception Filter — это специальный фильтр, предназначенный для глобальной или локальной обработки необработанных исключений, возникающих в конвейере обработки HTTP-запроса (в контроллерах, действиях, других фильтрах).

Основное назначение:

  • Централизованная обработка ошибок: Логирование исключений, преобразование технических исключений в пользовательские HTTP-ответы.
  • Контроль над ответом: Возможность вернуть клиенту специфичный формат (JSON, HTML) с нужным статус-кодом.

Пример реализации кастомного Exception Filter:

public class CustomExceptionFilter : IExceptionFilter
{
    private readonly ILogger<CustomExceptionFilter> _logger;

    public CustomExceptionFilter(ILogger<CustomExceptionFilter> logger)
    {
        _logger = logger;
    }

    public void OnException(ExceptionContext context)
    {
        // 1. Логируем исключение
        _logger.LogError(context.Exception, "Произошло необработанное исключение");

        // 2. Определяем, какой ответ вернуть
        var problemDetails = new ProblemDetails
        {
            Title = "Внутренняя ошибка сервера",
            Status = StatusCodes.Status500InternalServerError,
            Detail = "В процессе обработки запроса произошла ошибка.",
            Instance = context.HttpContext.Request.Path
        };

        // 3. Устанавливаем результат и помечаем исключение как обработанное
        context.Result = new ObjectResult(problemDetails)
        {
            StatusCode = problemDetails.Status
        };
        context.ExceptionHandled = true; // Важно: предотвращает дальнейшую обработку исключения
    }
}

// Регистрация фильтра глобально в Program.cs
builder.Services.AddControllers(options =>
{
    options.Filters.Add<CustomExceptionFilter>();
});

Альтернативы и best practices:

  • Middleware UseExceptionHandler: Часто является более предпочтительным способом для глобальной обработки исключений, так как перехватывает ошибки на более раннем этапе конвейера.
  • Атрибут [TypeFilter]: Для применения фильтра к конкретному контроллеру или действию.
  • Фильтры исключений полезны, когда нужна точечная обработка ошибок для определенной области приложения, в дополнение к глобальному обработчику.