Files
telegram-helper-bot/.cursor/rules/error-handling.md
Andrey feee7f010c refactor: обновление системы ML-скоринга и переход на RAG API
- Обновлен Dockerfile для использования Alpine вместо Slim, улучшая размер образа.
- Удален устаревший RAGService и добавлен RagApiClient для работы с внешним RAG API.
- Обновлены переменные окружения в env.example для настройки нового RAG API.
- Обновлен ScoringManager для интеграции с RagApiClient.
- Упрощена структура проекта, удалены ненужные файлы и зависимости, связанные с векторным хранилищем.
- Обновлены обработчики и функции для работы с новым API, включая получение статистики и обработку ошибок.
2026-01-26 22:03:15 +03:00

208 lines
8.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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()` - отладочная информация (детали выполнения, промежуточные значения, HTTP запросы(не используется в проекте))
- `logger.info()` - информационные сообщения о работе (успешные операции, важные события)
- `logger.warning()` - предупреждения о потенциальных проблемах (некритичные ошибки, таймауты)
- `logger.error()` - ошибки, требующие внимания (исключения, сбои)
- `logger.critical()` - критические ошибки
### Паттерн логирования в сервисах
При работе с внешними API и сервисами используйте следующий паттерн:
```python
from logs.custom_logger import logger
class ApiClient:
async def calculate_score(self, text: str) -> Score:
# Логируем начало операции (debug)
logger.debug(f"ApiClient: Отправка запроса на расчет скора (text_preview='{text[:50]}')")
try:
response = await self._client.post(url, json=data)
# Логируем статус ответа (debug)
logger.debug(f"ApiClient: Получен ответ (status={response.status_code})")
# Обрабатываем ответ
if response.status_code == 200:
result = response.json()
# Логируем успешный результат (info)
logger.info(f"ApiClient: Скор успешно получен (score={result['score']:.4f})")
return result
else:
# Логируем ошибку (error)
logger.error(f"ApiClient: Ошибка API (status={response.status_code})")
raise ApiError(f"Ошибка API: {response.status_code}")
except httpx.TimeoutException:
# Логируем таймаут (error)
logger.error(f"ApiClient: Таймаут запроса (>{timeout}с)")
raise
except httpx.RequestError as e:
# Логируем ошибку подключения (error)
logger.error(f"ApiClient: Ошибка подключения: {e}")
raise
except Exception as e:
# Логируем неожиданные ошибки (error)
logger.error(f"ApiClient: Неожиданная ошибка: {e}", exc_info=True)
raise
```
**Принципы:**
- `logger.debug()` - для деталей выполнения (URL, параметры запроса, статус ответа)
- `logger.info()` - для успешных операций с важными результатами
- `logger.warning()` - для некритичных проблем (валидация, таймауты в неважных операциях)
- `logger.error()` - для всех ошибок перед пробросом исключения
- Всегда логируйте ошибки перед `raise`
- Используйте `exc_info=True` для критических ошибок
## Метрики ошибок
Декоратор `@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