Closed allerter closed 3 years ago
Unfortunately. fastAPI cannot catch exceptions thrown in user‘s ASGI middleware.
You can use code similar to the following to solve this problem.
from ratelimit import RateLimitMiddleware
from ratelimit.auths import EmptyInformation
class CustomRateLimitMiddleware(RateLimitMiddleware):
async def __call__(self, scope, receive, send):
try:
await super().__call__(scope, receive, send)
except EmptyInformation:
response = JSONResponse(status_code=401, content={"detail": "Unauthorized access."})
await response(scope, receive, send)
Since we're adding a middleware here, it makes sense that FastAPI wouldn't catch the exception, but nonetheless, this sounds like a good solution. Thanks!
Why doesn't the package offer this by default like the on_blocked
parameter? Something like this would be nice:
async def send_401(scope: Scope, receive: Receive, send: Send, exc: EmptyInformation) -> None:
await send({"type": "http.response.start", "status": 401})
await send({"type": "http.response.body", "body": b"Unauthorized", "more_body": False})
app.add_middleware(
RateLimitMiddleware,
authenticate=AUTH_FUNCTION,
backend=RedisBackend(),
on_error=send_401, # or on_empty, on_auth_error, ...
config={
r"^/towns": [Rule(second=1, group="default"), Rule(group="admin")],
r"^/forests": [Rule(minute=1, group="default"), Rule(group="admin")],
},
)
This is a good idea. If you are interested, you can create a PR about it.
I'll send a PR soon.
I successfully set up the rate limiter for my app with
JWT
auth andRedisBacked
, but when I test it with requests that miss theAuthorization
header, the error isn't picked up by FastAPI and instead it results in anInternal Server Error
. I tried adding an exception handler forEmptyInformation
to send a 401 response back to the user, but the exception won't get picked up by the exception handler and still results in an Internal Server Error. Am I missing something here? What should I do to handle theEmptyInformation
exception?Code:
Version info
To reproduce: