Ответ
Да, работал. В контексте 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]: Для применения фильтра к конкретному контроллеру или действию. - Фильтры исключений полезны, когда нужна точечная обработка ошибок для определенной области приложения, в дополнение к глобальному обработчику.
Ответ 18+ 🔞
Да ты что, блядь, реально работал с этим? Ну ладно, слушай сюда, сейчас разжую как для дебила, только не ори потом, что непонятно.
Вот смотри, в этом ASP.NET Core есть такая штука — Exception Filter. Это типа такой мужик на стройке, который стоит и ловит все кирпичи, которые с крыши летят, пока другие работяги (твои контроллеры) косячат. Его задача — не дать этим кирпичам долбануть клиента по башке, а красиво подобрать, обернуть в бумажку и сказать: «Извините, у нас тут небольшие технические шоколадки».
Зачем он вообще нужен, этот фильтр?
- Чтобы не бегать с тряпкой по всему приложению. Вместо того чтобы в каждом методе писать
try-catchи одно и то же логирование, ты один раз настраиваешь этого ловца исключений, и он за всеми прибирает. Красота, а не жизнь. - Чтобы клиенту не светить голую ошибку с кучей стека. Представь, у тебя в базе данных кончилось место, а пользователь получает в ответе гигабайтный трейс с названиями таблиц и connection string. Это пиздец как небезопасно и непрофессионально. Фильтр позволяет сделать красивую, вменяемую ошибку.
Смотри, как это выглядит в коде, на простом примере:
public class MySuperExceptionFilter : IExceptionFilter
{
private readonly ILogger<MySuperExceptionFilter> _logger;
// Подтягиваем логгер, чтобы всё записывать. Без этого как без рук.
public MySuperExceptionFilter(ILogger<MySuperExceptionFilter> logger)
{
_logger = logger;
}
public void OnException(ExceptionContext context)
{
// 1. Первым делом — логируем в черный ящик. Что упало, где и почему.
_logger.LogError(context.Exception, "Ой, всё! Исключение в {Path}", context.HttpContext.Request.Path);
// 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<MySuperExceptionFilter>(); // Кинули его на весь проект
});
Но есть нюансы, блядь! Не бросайся сразу делать фильтр на всё.
- Middleware
UseExceptionHandler— часто круче. Этот парень ловит ошибки ещё раньше, до того как они до фильтров вообще долетят. Для глобальной поимки всех пиздюлей — это часто лучший выбор. - Фильтр — для точечной работы. Допустим, у тебя есть один особый контроллер для платёжек, где ошибки нужно логировать в отдельное место и возвращать особый формат. Вот тут фильтр, прицепленный только к нему (через
[TypeFilter]), будет в самый раз. - Не забывай про
ExceptionHandled = true. А то будешь потом сидеть и думать: «Ну я же всё написал, а ошибка всё равно прёт на клиента как ни в чём не бывало!». Это классическая ловушка для новичков.
Короче, инструмент нужный, но применять его надо с мозгом, а не просто потому что модно. Иногда проще и правильнее сделать один жирный UseExceptionHandler на всё приложение и не париться.