Skip to content

Websockets - RuntimeError: Not within a request context #419

@PabloExperimental

Description

@PabloExperimental

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions