Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AttributeError: 'WebSocketProtocol' object has no attribute 'transfer_data_task' #1396

Open
ondrejchmelar opened this issue Aug 29, 2023 · 2 comments
Labels

Comments

@ondrejchmelar
Copy link

When the client disconnects just after setting self.application_state = WebSocketState.CONNECTED, subsequent ws.close() will fail at .venv/lib/python3.11/site-packages/websockets/legacy/protocol.py:784 as transfer_data_task will not be set up.

I suppose it should be guarded by if hasattr(self, "transfer_data_task"): as it is in other places.

@aaugustin
Copy link
Member

Thank you for your report.

It shouldn't be possible to reach this line in close() before connection_open() completes successfully. I'd like to understand why this happens and, if applicable, to fix the root cause rather than just patch the symptom.

Could you provide a bit more details, please?

  1. Can you confirm that you talking about a client implemented with websockets?
  2. Can you provide the full stack trace? Ideally, debug logs too? (See https://websockets.readthedocs.io/en/stable/topics/logging.html#configure-logging)
  3. Do you have a minimum example that produces this behavior?

@aaugustin aaugustin added the bug label Oct 1, 2023
@hsteinhaus
Copy link

hsteinhaus commented May 1, 2024

+1 here:

2024-05-01 10:11:59,863 - ERROR    - Task-368  - uvicorn/protocols/websockets/websockets_impl.py - run_asgi             - Exception in ASGI application

Traceback (most recent call last):
  File "/data/myapp-yocto/myapp-appl/myapp-backend/.venv/lib/python3.12/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 240, in run_asgi
    result = await self.app(self.scope, self.asgi_receive, self.asgi_send)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/myapp-yocto/myapp-appl/myapp-backend/.venv/lib/python3.12/site-packages/uvicorn/middleware/proxy_headers.py", line 69, in __call__
    return await self.app(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/myapp-yocto/myapp-appl/myapp-backend/.venv/lib/python3.12/site-packages/fastapi/applications.py", line 1054, in __call__
    await super().__call__(scope, receive, send)
  File "/data/myapp-yocto/myapp-appl/myapp-backend/.venv/lib/python3.12/site-packages/starlette/applications.py", line 123, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/data/myapp-yocto/myapp-appl/myapp-backend/.venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 151, in __call__
    await self.app(scope, receive, send)
  File "/data/myapp-yocto/myapp-appl/myapp-backend/.venv/lib/python3.12/site-packages/starlette/middleware/cors.py", line 77, in __call__
    await self.app(scope, receive, send)
  File "/data/myapp-yocto/myapp-appl/myapp-backend/.venv/lib/python3.12/site-packages/starlette/middleware/exceptions.py", line 65, in __call__
    await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
  File "/data/myapp-yocto/myapp-appl/myapp-backend/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 64, in wrapped_app
    raise exc
  File "/data/myapp-yocto/myapp-appl/myapp-backend/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
    await app(scope, receive, sender)
  File "/data/myapp-yocto/myapp-appl/myapp-backend/.venv/lib/python3.12/site-packages/starlette/routing.py", line 756, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/data/myapp-yocto/myapp-appl/myapp-backend/.venv/lib/python3.12/site-packages/starlette/routing.py", line 776, in app
    await route.handle(scope, receive, send)
  File "/data/myapp-yocto/myapp-appl/myapp-backend/.venv/lib/python3.12/site-packages/starlette/routing.py", line 373, in handle
    await self.app(scope, receive, send)
  File "/data/myapp-yocto/myapp-appl/myapp-backend/.venv/lib/python3.12/site-packages/starlette/routing.py", line 96, in app
    await wrap_app_handling_exceptions(app, session)(scope, receive, send)
  File "/data/myapp-yocto/myapp-appl/myapp-backend/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 64, in wrapped_app
    raise exc
  File "/data/myapp-yocto/myapp-appl/myapp-backend/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
    await app(scope, receive, sender)
  File "/data/myapp-yocto/myapp-appl/myapp-backend/.venv/lib/python3.12/site-packages/starlette/routing.py", line 94, in app
    await func(session)
  File "/data/myapp-yocto/myapp-appl/myapp-backend/.venv/lib/python3.12/site-packages/fastapi/routing.py", line 348, in app
    await dependant.call(**values)
  File "/data/myapp-yocto/myapp-appl/myapp-backend/src/myapp_backend/api_v1/routes/device.py", line 68, in websocket_endpoint  # this is my application
    async with ws_connection(ws, serial, timeout=1) as messages:
  File "/usr/lib64/python3.12/contextlib.py", line 217, in __aexit__
    await anext(self.gen)
  File "/data/myapp-yocto/myapp-appl/myapp-backend/src/myapp_backend/api_v1/routes/websocket.py", line 80, in ws_connection
  File "/data/myapp-yocto/myapp-appl/myapp-backend/.venv/lib/python3.12/site-packages/starlette/websockets.py", line 203, in close
    await self.send(
  File "/data/myapp-yocto/myapp-appl/myapp-backend/.venv/lib/python3.12/site-packages/starlette/websockets.py", line 97, in send
    await self._send(message)
  File "/data/myapp-yocto/myapp-appl/myapp-backend/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 50, in sender
    await send(message)
  File "/data/myapp-yocto/myapp-appl/myapp-backend/.venv/lib/python3.12/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 337, in asgi_send
    await self.close(code, reason)
  File "/data/myapp-yocto/myapp-appl/myapp-backend/.venv/lib64/python3.12/site-packages/websockets/legacy/protocol.py", line 788, in close
    await self.transfer_data_task
          ^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'WebSocketProtocol' object has no attribute 'transfer_data_task'. Did you mean: 'transfer_data_exc'?

The issue occured while doing some evil concurrent load/abort/reload clicking of a Javascript/Vue.js-based page connecting to my websocket using the vueuse useWebsocket composable. See https://vueuse.org/core/useWebSocket/ for details of the client.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants