Обновлены пути к библиотекам в Dockerfile для соответствия новой версии Python. Исправлены все тесты, теперь все проходят
157 lines
5.6 KiB
Markdown
157 lines
5.6 KiB
Markdown
---
|
||
description: "Обработка ошибок, исключения и логирование"
|
||
alwaysApply: false
|
||
---
|
||
|
||
# Обработка ошибок и исключений
|
||
|
||
## Иерархия исключений
|
||
|
||
Каждый модуль должен иметь свой файл `exceptions.py` с иерархией исключений:
|
||
|
||
```python
|
||
# Базовое исключение модуля
|
||
class ModuleError(Exception):
|
||
"""Базовое исключение для модуля"""
|
||
pass
|
||
|
||
# Специализированные исключения
|
||
class UserNotFoundError(ModuleError):
|
||
"""Исключение при отсутствии пользователя"""
|
||
pass
|
||
|
||
class InvalidInputError(ModuleError):
|
||
"""Исключение при некорректном вводе данных"""
|
||
pass
|
||
```
|
||
|
||
## Обработка в Handlers
|
||
|
||
### Паттерн try-except
|
||
|
||
```python
|
||
@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` для автоматической обработки:
|
||
|
||
```python
|
||
from .decorators import error_handler
|
||
|
||
@error_handler
|
||
@router.message(...)
|
||
async def handler(...):
|
||
# Код handler
|
||
# Ошибки автоматически логируются и отправляются в important_logs
|
||
...
|
||
```
|
||
|
||
## Обработка в Services
|
||
|
||
```python
|
||
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`:
|
||
|
||
```python
|
||
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` автоматически отслеживает ошибки:
|
||
|
||
```python
|
||
@track_errors("module_name", "method_name")
|
||
async def some_method():
|
||
# Ошибки автоматически записываются в метрики
|
||
...
|
||
```
|
||
|
||
## Централизованная обработка
|
||
|
||
### В admin handlers
|
||
|
||
Используется функция `handle_admin_error()`:
|
||
|
||
```python
|
||
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
|
||
|
||
1. **Всегда логируйте ошибки** перед пробросом или обработкой
|
||
2. **Используйте специфичные исключения** вместо общих `Exception`
|
||
3. **Пробрасывайте исключения** из сервисов в handlers для обработки
|
||
4. **Не глотайте исключения** без логирования
|
||
5. **Используйте `exc_info=True`** для логирования traceback критических ошибок
|
||
6. **Обрабатывайте ошибки на правильном уровне**: бизнес-логика в сервисах, пользовательские сообщения в handlers
|