Strange error with starlette / fastapi
aersam opened this issue · comments
Hi there
I've been trying to use startlette on some app of mine, and it worked well locally. In production however I get this strange error:
2024-06-07T11:34:36.7225565Z [ERROR] Application callable raised an exception
2024-06-07T11:34:36.7225739Z Traceback (most recent call last):
2024-06-07T11:34:36.7225904Z File "/tmp/8dc86c846d0f82f/antenv/lib/python3.12/site-packages/granian/_futures.py", line 4, in future_watcher
2024-06-07T11:34:36.7226079Z await inner(watcher.scope, watcher.proto)
2024-06-07T11:34:36.7226217Z File "/tmp/8dc86c846d0f82f/antenv/lib/python3.12/site-packages/fastapi/applications.py", line 1054, in __call__
2024-06-07T11:34:36.7226374Z await super().__call__(scope, receive, send)
2024-06-07T11:34:36.7226523Z File "/tmp/8dc86c846d0f82f/antenv/lib/python3.12/site-packages/starlette/applications.py", line 123, in __call__
2024-06-07T11:34:36.7226660Z await self.middleware_stack(scope, receive, send)
2024-06-07T11:34:36.7226814Z File "/tmp/8dc86c846d0f82f/antenv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 186, in __call__
2024-06-07T11:34:36.7226968Z raise exc
2024-06-07T11:34:36.7227101Z File "/tmp/8dc86c846d0f82f/antenv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 164, in __call__
2024-06-07T11:34:36.7227252Z await self.app(scope, receive, _send)
2024-06-07T11:34:36.7227387Z File "/tmp/8dc86c846d0f82f/antenv/lib/python3.12/site-packages/starlette/middleware/base.py", line 189, in __call__
2024-06-07T11:34:36.7227541Z with collapse_excgroups():
2024-06-07T11:34:36.7227683Z File "/opt/python/3.12.2/lib/python3.12/contextlib.py", line 158, in __exit__
2024-06-07T11:34:36.7228228Z self.gen.throw(value)
2024-06-07T11:34:36.7228459Z File "/tmp/8dc86c846d0f82f/antenv/lib/python3.12/site-packages/starlette/_utils.py", line 93, in collapse_excgroups
2024-06-07T11:34:36.7228673Z raise exc
2024-06-07T11:34:36.7228908Z File "/tmp/8dc86c846d0f82f/antenv/lib/python3.12/site-packages/starlette/responses.py", line 261, in wrap
2024-06-07T11:34:36.7229135Z await func()
2024-06-07T11:34:36.7229335Z File "/tmp/8dc86c846d0f82f/antenv/lib/python3.12/site-packages/starlette/middleware/base.py", line 217, in stream_response
2024-06-07T11:34:36.7229559Z return await super().stream_response(send)
2024-06-07T11:34:36.7229770Z ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-06-07T11:34:36.7229969Z File "/tmp/8dc86c846d0f82f/antenv/lib/python3.12/site-packages/starlette/responses.py", line 250, in stream_response
2024-06-07T11:34:36.7230213Z async for chunk in self.body_iterator:
2024-06-07T11:34:36.7230411Z File "/tmp/8dc86c846d0f82f/antenv/lib/python3.12/site-packages/starlette/middleware/base.py", line 173, in body_stream
2024-06-07T11:34:36.7230571Z assert message["type"] == "http.response.body"
My startup command is granian application:app --host 0.0.0.0 --port 8000 --workers 2 --interface asgi --loop asyncio
The route producing the error is very simple (starlette/fastapi)
rr = RedirectResponse(flow["auth_uri"])
rr.set_cookie("flow", json.dumps(flow, default=str), max_age=180) # Temp cookie during auth flow
rr.headers.append("Cache-Control", "no-cache, max-age=0")
return rr
Any idea what could cause such an error?
This looks like #216.
Even after the long discussions and debugging, it's still unclear to me why Starlette fails in using its own response stream code (that assertion checks a ASGI message sent by starlette, not Granian).
I don't have any quick solution for this, I might spend some time trying to debug Starlette internals with Granian in the following weeks, but I'm not sure it will lead to any result.
Just a quick thing: any specific reason you're explicitly avoiding uvloop
on a Unix OS? My gut tells me this is some concurrency issue with Starlette, uvloop might just automagically solve it.
The --loop was just an attempt to fix it, it's the same behavior. FYI: My Production Environment uses Linux and Python 3.12, it's an azure website
@aersam can you please provide a MRE including (but not limited to) the list of middlewares you're using?
The MRE is hard since I could not reproduce this, not on Windows nor on WSL. But I monkey-patched Starlette and have a better error message now :)
AssertionError: Unexpected message of type http.response.pathsend from class <class 'starlette.middleware.base.BaseHTTPMiddleware'>: {'type': 'http.response.pathsend', 'path': 'frontend_app/output/index.html'}
The MRE is hard since I could not reproduce this, not on Windows nor on WSL. But I monkey-patched Starlette and have a better error message now :)
AssertionError: Unexpected message of type http.response.pathsend from class <class 'starlette.middleware.base.BaseHTTPMiddleware'>: {'type': 'http.response.pathsend', 'path': 'frontend_app/output/index.html'}
Oh, that's actually a Starlette bug then!
Can you please open an issue in the Starlette repo mentioning this as the starting point?
cc @Kludex
I'm closing this since we now have encode/starlette#2613 and encode/starlette#2616