Handle session commit failure with rollback and do not re-raise
This commit is contained in:
+28
-19
@@ -7,36 +7,47 @@ 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:
|
||||
handler_name = getattr(handler, "__qualname__", getattr(handler, "__name__", str(handler)))
|
||||
event_type = type(event).__name__
|
||||
logger.warning(
|
||||
"Session commit failed, rollback performed — handler=%s, event=%s, error=%s: %s",
|
||||
"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,
|
||||
)
|
||||
try:
|
||||
await session.rollback()
|
||||
except Exception:
|
||||
pass
|
||||
raise commit_err
|
||||
return result
|
||||
await self._rollback(session, "commit failure")
|
||||
return result
|
||||
except Exception as e:
|
||||
handler_name = getattr(handler, "__qualname__", getattr(handler, "__name__", str(handler)))
|
||||
event_type = type(event).__name__
|
||||
logger.warning(
|
||||
"Session rollback: ошибка при обработке — handler=%s, event=%s, error=%s: %s",
|
||||
handler_name,
|
||||
@@ -45,16 +56,14 @@ class SessionMiddleware(BaseMiddleware):
|
||||
e,
|
||||
exc_info=True,
|
||||
)
|
||||
try:
|
||||
await session.rollback()
|
||||
except Exception:
|
||||
pass
|
||||
await self._rollback(session, "handler failure")
|
||||
raise
|
||||
finally:
|
||||
try:
|
||||
await session.rollback()
|
||||
except Exception:
|
||||
pass
|
||||
if not committed:
|
||||
try:
|
||||
await session.rollback()
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
await session.close()
|
||||
except Exception:
|
||||
|
||||
Reference in New Issue
Block a user