Обновлены пути к библиотекам в Dockerfile для соответствия новой версии Python. Исправлены все тесты, теперь все проходят
5.6 KiB
5.6 KiB
description, alwaysApply
| description | alwaysApply |
|---|---|
| Обработка ошибок, исключения и логирование | false |
Обработка ошибок и исключений
Иерархия исключений
Каждый модуль должен иметь свой файл exceptions.py с иерархией исключений:
# Базовое исключение модуля
class ModuleError(Exception):
"""Базовое исключение для модуля"""
pass
# Специализированные исключения
class UserNotFoundError(ModuleError):
"""Исключение при отсутствии пользователя"""
pass
class InvalidInputError(ModuleError):
"""Исключение при некорректном вводе данных"""
pass
Обработка в Handlers
Паттерн try-except
@router.message(...)
async def handler(message: types.Message, state: FSMContext, **kwargs):
try:
# Основная логика
service = SomeService(bot_db, settings)
result = await service.do_something()
await message.answer("Успех")
except UserNotFoundError as e:
# Обработка специфичной ошибки
await message.answer(f"Пользователь не найден: {str(e)}")
logger.warning(f"Пользователь не найден: {e}")
except InvalidInputError as e:
# Обработка ошибки валидации
await message.answer(f"Некорректный ввод: {str(e)}")
logger.warning(f"Некорректный ввод: {e}")
except Exception as e:
# Обработка неожиданных ошибок
await handle_error(message, e, state)
logger.error(f"Неожиданная ошибка в handler: {e}", exc_info=True)
Декоратор error_handler
Некоторые модули используют декоратор @error_handler для автоматической обработки:
from .decorators import error_handler
@error_handler
@router.message(...)
async def handler(...):
# Код handler
# Ошибки автоматически логируются и отправляются в important_logs
...
Обработка в Services
class SomeService:
async def do_something(self):
try:
# Бизнес-логика
data = await self.bot_db.get_data()
if not data:
raise UserNotFoundError("Пользователь не найден")
return self._process(data)
except UserNotFoundError:
# Пробрасываем специфичные исключения дальше
raise
except Exception as e:
# Логируем и пробрасываем неожиданные ошибки
logger.error(f"Ошибка в сервисе: {e}", exc_info=True)
raise
Логирование
Использование logger
Всегда используйте logs.custom_logger.logger:
from logs.custom_logger import logger
# Информационные сообщения
logger.info(f"Пользователь {user_id} выполнил действие")
# Предупреждения
logger.warning(f"Попытка доступа к несуществующему ресурсу: {resource_id}")
# Ошибки
logger.error(f"Ошибка при выполнении операции: {e}")
# Ошибки с traceback
logger.error(f"Критическая ошибка: {e}", exc_info=True)
Уровни логирования
logger.debug()- отладочная информацияlogger.info()- информационные сообщения о работеlogger.warning()- предупреждения о потенциальных проблемахlogger.error()- ошибки, требующие вниманияlogger.critical()- критические ошибки
Метрики ошибок
Декоратор @track_errors автоматически отслеживает ошибки:
@track_errors("module_name", "method_name")
async def some_method():
# Ошибки автоматически записываются в метрики
...
Централизованная обработка
В admin handlers
Используется функция handle_admin_error():
from helper_bot.handlers.admin.utils import handle_admin_error
try:
# Код
except Exception as e:
await handle_admin_error(message, e, state, "context_name")
В других модулях
Создавайте аналогичные утилиты для централизованной обработки ошибок модуля.
Best Practices
- Всегда логируйте ошибки перед пробросом или обработкой
- Используйте специфичные исключения вместо общих
Exception - Пробрасывайте исключения из сервисов в handlers для обработки
- Не глотайте исключения без логирования
- Используйте
exc_info=Trueдля логирования traceback критических ошибок - Обрабатывайте ошибки на правильном уровне: бизнес-логика в сервисах, пользовательские сообщения в handlers