71 lines
2.4 KiB
Python
71 lines
2.4 KiB
Python
from aiogram import BaseMiddleware
|
|
|
|
from logger import logger
|
|
|
|
|
|
class SessionMiddleware(BaseMiddleware):
|
|
def __init__(self, sessionmaker):
|
|
self.sessionmaker = sessionmaker
|
|
|
|
async def _rollback(self, session, context: str) -> None:
|
|
"""Attempt rollback so invalid transaction is cleared; log if rollback fails."""
|
|
try:
|
|
await session.rollback()
|
|
except Exception as rollback_err:
|
|
logger.warning(
|
|
"Session rollback failed during %s — %s: %s",
|
|
context,
|
|
type(rollback_err).__name__,
|
|
rollback_err,
|
|
exc_info=True,
|
|
)
|
|
|
|
async def __call__(self, handler, event, data):
|
|
if data.get("session"):
|
|
return await handler(event, data)
|
|
|
|
session = self.sessionmaker()
|
|
data["session"] = session
|
|
committed = False
|
|
handler_name = getattr(handler, "__qualname__", getattr(handler, "__name__", str(handler)))
|
|
event_type = type(event).__name__
|
|
|
|
try:
|
|
result = await handler(event, data)
|
|
try:
|
|
await session.commit()
|
|
committed = True
|
|
return result
|
|
except Exception as commit_err:
|
|
logger.warning(
|
|
"Session commit failed, rolling back (ошибка не пробрасывается) — handler=%s, event=%s, error=%s: %s",
|
|
handler_name,
|
|
event_type,
|
|
type(commit_err).__name__,
|
|
commit_err,
|
|
exc_info=True,
|
|
)
|
|
await self._rollback(session, "commit failure")
|
|
return result
|
|
except Exception as e:
|
|
logger.warning(
|
|
"Session rollback: ошибка при обработке — handler=%s, event=%s, error=%s: %s",
|
|
handler_name,
|
|
event_type,
|
|
type(e).__name__,
|
|
e,
|
|
exc_info=True,
|
|
)
|
|
await self._rollback(session, "handler failure")
|
|
raise
|
|
finally:
|
|
if not committed:
|
|
try:
|
|
await session.rollback()
|
|
except Exception:
|
|
pass
|
|
try:
|
|
await session.close()
|
|
except Exception:
|
|
pass
|