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:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user