Describe the bug
In case of ConnectionError from Redis (and acutally any error raised from storage access), traceback is swallowed along the way, so that I had to guess what was the reason of the problem (in my case redis.ConnectionError was raised, I'm still not 100% sure why).
Produced traceback looks like this:
File "/src/.venv/lib/python3.12/site-packages/uvicorn/protocols/http/h11_impl.py", line 396, in run_asgi
result = await app( # type: ignore[func-returns-value]
File "/src/.venv/lib/python3.12/site-packages/uvicorn/middleware/proxy_headers.py", line 70, in __call__
return await self.app(scope, receive, send)
File "/src/.venv/lib/python3.12/site-packages/fastapi/applications.py", line 1054, in __call__
await super().__call__(scope, receive, send)
File "/src/.venv/lib/python3.12/site-packages/starlette/applications.py", line 123, in __call__
await self.middleware_stack(scope, receive, send)
File "/src/.venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 186, in __call__
raise exc
File "/src/.venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 164, in __call__
await self.app(scope, receive, _send)
File "/src/.venv/lib/python3.12/site-packages/starlette/middleware/base.py", line 189, in __call__
with collapse_excgroups():
File "/usr/local/lib/python3.12/contextlib.py", line 158, in __exit__
self.gen.throw(value)
File "/src/.venv/lib/python3.12/site-packages/starlette/_utils.py", line 93, in collapse_excgroups
raise exc
File "/src/.venv/lib/python3.12/site-packages/starlette/middleware/base.py", line 191, in __call__
response = await self.dispatch_func(request, call_next)
File "/src/.venv/lib/python3.12/site-packages/slowapi/middleware.py", line 130, in dispatch
error_response, should_inject_headers = sync_check_limits(
File "/src/.venv/lib/python3.12/site-packages/slowapi/middleware.py", line 77, in sync_check_limits
return exception_handler(request, exc), _bool # type: ignore
File "/src/.venv/lib/python3.12/site-packages/slowapi/extension.py", line 81, in _rate_limit_exceeded_handler
{"error": f"Rate limit exceeded: {exc.detail}"}, status_code=429
AttributeError: 'ConnectionError' object has no attribute 'detail'
but the default handler is the one for handling SPECIFIC errors from rate limiting, it is not prepared to handle all exceptions.
I think it would be good to separate the logic for handling rate limit errors from other errors.
Workarounds
In my case it was good enough to add in_memory_fallback_enabled=True,. Slowapi is smart enough to reconnect when storage is up. But this approach has an unpleasant side effect that real problems are hidden.
Alternatively one could register event handler to do custom work, but I not tested this path.
Describe the bug In case of ConnectionError from Redis (and acutally any error raised from storage access), traceback is swallowed along the way, so that I had to guess what was the reason of the problem (in my case
redis.ConnectionError
was raised, I'm still not 100% sure why).Produced traceback looks like this:
To Reproduce
Expected behavior Error should be raised with correct traceback
Your app (please complete the following information):
Additional context
I think it would be good to separate the logic for handling rate limit errors from other errors.
Workarounds
In my case it was good enough to add
in_memory_fallback_enabled=True,
. Slowapi is smart enough to reconnect when storage is up. But this approach has an unpleasant side effect that real problems are hidden.Alternatively one could register event handler to do custom work, but I not tested this path.