fix: Circuit Breaker only triggers on transient DB errors, not HTTP exceptions

The CircuitBreakerMiddleware was blocking all requests (503 circuit_open) because
every exception in get_db() — including 401 Unauthorized, 403 Forbidden, 404 Not Found —
was calling record_failure() on the DB circuit breaker. This caused the circuit to
trip after 5 non-DB errors (e.g. failed login attempts during security testing).

Fix: Only call record_failure() when _is_transient_db_error(exc) returns True,
filtering out HTTP exceptions that are not DB-related.
This commit is contained in:
Agent Zero
2026-08-04 19:43:47 +02:00
parent 17765e47b4
commit efba5ceb9c
+5 -3
View File
@@ -224,7 +224,7 @@ async def get_db() -> AsyncGenerator[AsyncSession, None]:
Used for normal API requests with tenant context set via RLS.
Includes retry logic for transient connection errors.
"""
from app.core.resilience import get_circuit, retry_db
from app.core.resilience import get_circuit, retry_db, _is_transient_db_error
async def _get_session():
factory = get_session_factory()
@@ -235,9 +235,11 @@ async def get_db() -> AsyncGenerator[AsyncSession, None]:
yield session
await session.commit()
await get_circuit("db").record_success()
except Exception:
except Exception as exc:
await session.rollback()
await get_circuit("db").record_failure()
# Only record DB circuit failure for transient DB errors, not HTTP exceptions
if _is_transient_db_error(exc):
await get_circuit("db").record_failure()
raise
finally:
await session.close()