quart icon indicating copy to clipboard operation
quart copied to clipboard

Websockets - RuntimeError: Not within a request context

Open PabloExperimental opened this issue 9 months ago • 0 comments

When I close my application and the websocket is active, the server raise this uncaught stack of exception:

service    | Traceback (most recent call last):
service    |   File "/usr/local/lib/python3.13/site-packages/uvicorn/protocols/websockets/wsproto_impl.py", line 331, in send
service    |     output = self.conn.send(wsproto.events.Message(data=data))  # type: ignore
service    |   File "/usr/local/lib/python3.13/site-packages/wsproto/__init__.py", line 64, in send
service    |     data += self.connection.send(event)                                                                                                                           
service    |             ~~~~~~~~~~~~~~~~~~~~^^^^^^^                                                                                                                           
service    |   File "/usr/local/lib/python3.13/site-packages/wsproto/connection.py", line 107, in send                                                                         
service    |     raise LocalProtocolError(                                                                                                                                     
service    |         f"Event {event} cannot be sent in state {self.state}."                                                                                                    
service    |     )
service    | wsproto.utilities.LocalProtocolError: Event Message(data='0', frame_finished=True, message_finished=True) cannot be sent in state ConnectionState.CLOSED.         
service    |                                                                                                                                                                   
service    | The above exception was the direct cause of the following exception:
service    |                                                                                                                                                                   
service    | Traceback (most recent call last):                                                                                                                                
service    |   File "${MY_PATH}/notifications_route.py", line 109, in author_get_number_notification_unread
service    |     await websocket.send(str(result))
service    |   File "/usr/local/lib/python3.13/site-packages/quart/wrappers/websocket.py", line 68, in send                                                                    
service    |     await self._send(data)
service    |   File "/usr/local/lib/python3.13/site-packages/quart/asgi.py", line 311, in send_data                                                                            
service    |     await send({"type": "websocket.send", "bytes": None, "text": data})                                                                                           
service    |   File "/usr/local/lib/python3.13/site-packages/uvicorn/protocols/websockets/wsproto_impl.py", line 350, in send                                                  
service    |     raise ClientDisconnected from exc                                                                                                                             
service    | uvicorn.protocols.utils.ClientDisconnected                                                                                                                        
service    | [2025-03-06 12:15:10,875] ERROR in app: Exception on websocket /ws/author/notifications/unread
service    | Traceback (most recent call last):
service    |   File "/usr/local/lib/python3.13/site-packages/uvicorn/protocols/websockets/wsproto_impl.py", line 331, in send                                                  
service    |     output = self.conn.send(wsproto.events.Message(data=data))  # type: ignore                                                                                    
service    |   File "/usr/local/lib/python3.13/site-packages/wsproto/__init__.py", line 64, in send                                                                            
service    |     data += self.connection.send(event)                                                                                                                           
service    |             ~~~~~~~~~~~~~~~~~~~~^^^^^^^                                                                                                                           
service    |   File "/usr/local/lib/python3.13/site-packages/wsproto/connection.py", line 107, in send                                                                         
service    |     raise LocalProtocolError(
service    |         f"Event {event} cannot be sent in state {self.state}."
service    |     )                                                                                                                                                             
service    | wsproto.utilities.LocalProtocolError: Event Message(data='0', frame_finished=True, message_finished=True) cannot be sent in state ConnectionState.CLOSED.         
service    |                                                                                                                                                                   
service    | The above exception was the direct cause of the following exception:                                                                                              
service    |                                                                                                                                                                   
service    | Traceback (most recent call last):                                                                                                                                
service    |   File "${MY_PATH}/notifications_route.py", line 109, in author_get_number_notification_unread                                        
service    |     await websocket.send(str(result))                                                                                                                             
service    |   File "/usr/local/lib/python3.13/site-packages/quart/wrappers/websocket.py", line 68, in send                                                                    
service    |     await self._send(data)                                                                                                                                        
service    |   File "/usr/local/lib/python3.13/site-packages/quart/asgi.py", line 311, in send_data                                                                            
service    |     await send({"type": "websocket.send", "bytes": None, "text": data})
service    |   File "/usr/local/lib/python3.13/site-packages/uvicorn/protocols/websockets/wsproto_impl.py", line 350, in send                                                  
service    |     raise ClientDisconnected from exc                                                                                                                             
service    | uvicorn.protocols.utils.ClientDisconnected                                                                                                                        
service    |                                                                                                                                                                   
service    | During handling of the above exception, another exception occurred:                                                                                               
service    |                                                                                                                                                                   
service    | Traceback (most recent call last):                                                                                                                                
service    |   File "/usr/local/lib/python3.13/site-packages/uvicorn/protocols/websockets/wsproto_impl.py", line 341, in send
service    |     output = self.conn.send(wsproto.events.CloseConnection(code=code, reason=reason))                                                                             
service    |   File "/usr/local/lib/python3.13/site-packages/wsproto/__init__.py", line 64, in send                                                                            
service    |     data += self.connection.send(event)                                                                                                                           
service    |             ~~~~~~~~~~~~~~~~~~~~^^^^^^^                                                                                                                           
service    |   File "/usr/local/lib/python3.13/site-packages/wsproto/connection.py", line 107, in send                                                                         
service    |     raise LocalProtocolError(                                                                                                                                     
service    |         f"Event {event} cannot be sent in state {self.state}."                                                                                                    
service    |     )                                                                                                                                                             
service    | wsproto.utilities.LocalProtocolError: Event CloseConnection(code=1000, reason='') cannot be sent in state ConnectionState.CLOSED.
service    |                                                                                                                                                                   
service    | The above exception was the direct cause of the following exception:                                                                                              
service    |                                                                                                                                                                   
service    | Traceback (most recent call last):                                                                                                                                
service    |   File "/usr/local/lib/python3.13/site-packages/quart/app.py", line 1476, in handle_websocket                                                                     
service    |     return await self.full_dispatch_websocket(websocket_context)                                                                                                  
service    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                                                                                  
service    |   File "/usr/local/lib/python3.13/site-packages/quart/app.py", line 1525, in full_dispatch_websocket                                                              
service    |     result = await self.handle_user_exception(error)                                                                                                              
service    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                                                                                              
service    |   File "/usr/local/lib/python3.13/site-packages/quart/app.py", line 1059, in handle_user_exception                                                                
service    |     raise error
service    |   File "/usr/local/lib/python3.13/site-packages/quart/app.py", line 1523, in full_dispatch_websocket                                                              
service    |     result = await self.dispatch_websocket(websocket_context)                                                                                                     
service    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                                                                                     
service    |   File "/usr/local/lib/python3.13/site-packages/quart/app.py", line 1613, in dispatch_websocket                                                                   
service    |     return await self.ensure_async(handler)(**websocket_.view_args)  # type: ignore[return-value]                                                                 
service    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                                                                               
service    |   File "${MY_PATH}/notifications_route.py", line 129, in author_get_number_notification_unread                                        
service    |     await websocket.close(1000)                                                                                                                                   
service    |   File "/usr/local/lib/python3.13/site-packages/quart/wrappers/websocket.py", line 104, in close                                                                  
service    |     await self._close(code, reason)                                                                                                                               
service    |   File "/usr/local/lib/python3.13/site-packages/quart/asgi.py", line 348, in close_connection                                                                     
service    |     await send({"type": "websocket.close", "code": code, "reason": reason})                                                                                       
service    |   File "/usr/local/lib/python3.13/site-packages/uvicorn/protocols/websockets/wsproto_impl.py", line 350, in send
service    |     raise ClientDisconnected from exc                                                                                                                             
service    | uvicorn.protocols.utils.ClientDisconnected                                                                                                                        
service    | ERROR:    Exception in ASGI application                                                                                                                           
service    | Traceback (most recent call last):                                                                                                                                
service    |   File "/usr/local/lib/python3.13/site-packages/uvicorn/protocols/websockets/wsproto_impl.py", line 235, in run_asgi                                              
service    |     result = await self.app(self.scope, self.receive, self.send)  # type: ignore[func-returns-value]                                                              
service    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                                                                                  
service    |   File "/usr/local/lib/python3.13/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__                                                        
service    |     return await self.app(scope, receive, send)
service    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                                                                                                   
service    |   File "/usr/local/lib/python3.13/site-packages/quart/app.py", line 1735, in __call__                                                                             
service    |     await self.asgi_app(scope, receive, send)                                                                                                                     
service    |   File "/usr/local/lib/python3.13/site-packages/quart/app.py", line 1761, in asgi_app                                                                             
service    |     await asgi_handler(receive, send)                                                                                                                             
service    |   File "/usr/local/lib/python3.13/site-packages/quart/asgi.py", line 197, in __call__                                                                             
service    |     raise_task_exceptions(done)                                                                                                                                   
service    |     ~~~~~~~~~~~~~~~~~~~~~^^^^^^                                                                                                                                   
service    |   File "/usr/local/lib/python3.13/site-packages/quart/utils.py", line 186, in raise_task_exceptions                                                               
service    |     raise task.exception()                                                                                                                                        
service    |   File "/usr/local/lib/python3.13/site-packages/quart/asgi.py", line 246, in handle_websocket                                                                     
service    |     response = await _handle_exception(self.app, error)                                                                                                           
service    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                                                                                           
service    |   File "/usr/local/lib/python3.13/site-packages/quart/asgi.py", line 408, in _handle_exception
service    |     raise error                                                                                                                                                   
service    |   File "/usr/local/lib/python3.13/site-packages/quart/asgi.py", line 244, in handle_websocket                                                                     
service    |     response = await self.app.handle_websocket(websocket)                                                                                                         
service    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                                                                                         
service    |   File "/usr/local/lib/python3.13/site-packages/quart/app.py", line 1480, in handle_websocket                                                                     
service    |     return await self.handle_websocket_exception(error)                                                                                                           
service    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                                                                                           
service    |   File "/usr/local/lib/python3.13/site-packages/quart/app.py", line 1129, in handle_websocket_exception                                                           
service    |     server_error = await self.ensure_async(handler)(server_error)  # type: ignore[assignment]                                                                     
service    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                                                                                 
service    |   File "/usr/local/lib/python3.13/site-packages/quart_cors/__init__.py", line 110, in wrapper
service    |     method = request.method
service    |              ^^^^^^^^^^^^^^
service    |   File "/usr/local/lib/python3.13/site-packages/werkzeug/local.py", line 318, in __get__
service    |     obj = instance._get_current_object()
service    |   File "/usr/local/lib/python3.13/site-packages/werkzeug/local.py", line 519, in _get_current_object
service    |     raise RuntimeError(unbound_message) from None
service    | RuntimeError: Not within a request context

How can I solve this?

Update: Maybe I found the solution. I just don't have to call await websocket.close(1000) if the user is already gone, removing it doesn't make appear again the error. Is this correct?

Environment:

  • Python version: 3.13-slim-bookworm or 3.12-slim-bookworm + uvicorn
  • Quart version: 0.20

PabloExperimental avatar Mar 06 '25 12:03 PabloExperimental