Files
telegram-helper-bot/.cursor/rules/middleware-patterns.md
Andrey d2d7c83575 Обновлен Python до версии 3.11.9 и изменены зависимости в Dockerfile и pyproject.toml. Удалены устаревшие файлы RATE_LIMITING_SOLUTION.md и тесты для rate limiting.
Обновлены пути к библиотекам в Dockerfile для соответствия новой версии Python.
Исправлены все тесты, теперь все проходят
2026-01-25 16:07:27 +03:00

110 lines
3.7 KiB
Markdown
Raw 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: "Паттерны создания и использования middleware в aiogram"
globs: ["helper_bot/middlewares/**/*.py"]
---
# Паттерны Middleware
## Структура Middleware
Все middleware наследуются от `aiogram.BaseMiddleware`:
```python
from typing import Any, Dict
from aiogram import BaseMiddleware
from aiogram.types import TelegramObject
class CustomMiddleware(BaseMiddleware):
"""Описание middleware."""
async def __call__(
self,
handler: Callable,
event: TelegramObject,
data: Dict[str, Any]
) -> Any:
# Логика до обработки handler
...
# Вызов следующего handler в цепочке
result = await handler(event, data)
# Логика после обработки handler
...
return result
```
## Порядок регистрации Middleware
В `main.py` middleware регистрируются в следующем порядке (важно!):
```python
# 1. DependenciesMiddleware - внедрение зависимостей
dp.update.outer_middleware(DependenciesMiddleware())
# 2. MetricsMiddleware - сбор метрик
dp.update.outer_middleware(MetricsMiddleware())
# 3. BlacklistMiddleware - проверка черного списка
dp.update.outer_middleware(BlacklistMiddleware())
# 4. RateLimitMiddleware - ограничение частоты запросов
dp.update.outer_middleware(RateLimitMiddleware())
```
## DependenciesMiddleware
Внедряет глобальные зависимости во все handlers:
```python
class DependenciesMiddleware(BaseMiddleware):
async def __call__(self, handler, event: TelegramObject, data: Dict[str, Any]) -> Any:
bdf = get_global_instance()
# Внедрение зависимостей
if 'bot_db' not in data:
data['bot_db'] = bdf.get_db()
if 'settings' not in data:
data['settings'] = bdf.settings
return await handler(event, data)
```
## Обработка ошибок в Middleware
```python
class CustomMiddleware(BaseMiddleware):
async def __call__(self, handler, event, data):
try:
# Предобработка
...
result = await handler(event, data)
# Постобработка
...
return result
except Exception as e:
# Обработка ошибок
logger.error(f"Ошибка в middleware: {e}")
# Решаем: пробрасывать дальше или обработать
raise
```
## Регистрация на уровне Router
Middleware можно регистрировать на уровне конкретного router:
```python
router = Router()
router.message.middleware(SomeMiddleware()) # Только для message handlers
router.callback_query.middleware(SomeMiddleware()) # Только для callback handlers
```
## Best Practices
1. **Регистрируйте middleware в правильном порядке** - зависимости должны быть первыми
2. **Не изменяйте event** напрямую, используйте `data` для передачи информации
3. **Обрабатывайте ошибки** в middleware, но не глотайте их без логирования
4. **Используйте `outer_middleware`** для глобальной регистрации
5. **Используйте `router.middleware()`** для локальной регистрации на уровне модуля