Обновлены пути к библиотекам в Dockerfile для соответствия новой версии Python. Исправлены все тесты, теперь все проходят
3.7 KiB
3.7 KiB
description, globs
| description | globs | |
|---|---|---|
| Паттерны создания и использования middleware в aiogram |
|
Паттерны Middleware
Структура Middleware
Все middleware наследуются от aiogram.BaseMiddleware:
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 регистрируются в следующем порядке (важно!):
# 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:
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
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:
router = Router()
router.message.middleware(SomeMiddleware()) # Только для message handlers
router.callback_query.middleware(SomeMiddleware()) # Только для callback handlers
Best Practices
- Регистрируйте middleware в правильном порядке - зависимости должны быть первыми
- Не изменяйте event напрямую, используйте
dataдля передачи информации - Обрабатывайте ошибки в middleware, но не глотайте их без логирования
- Используйте
outer_middlewareдля глобальной регистрации - Используйте
router.middleware()для локальной регистрации на уровне модуля