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

Testing ASGI wrong message event #97

Open
cfytrok opened this issue Dec 26, 2024 · 3 comments · May be fixed by #101
Open

Testing ASGI wrong message event #97

cfytrok opened this issue Dec 26, 2024 · 3 comments · May be fixed by #101
Labels
bug Something isn't working

Comments

@cfytrok
Copy link

cfytrok commented Dec 26, 2024

Two problems:

  1. If not catch error except Exception as e: it is silenced.
  2. When disconnecting starlette receives websocket.close instead of websocket.disconnect.
    The problem seems to be here https://github.com/frankie567/httpx-ws/blob/main/httpx_ws/transport.py#L95
    websocket.close needs to be converted to websocket.disconnect, just like websocket.send is converted to websocket.receive
  import asyncio
  import logging
  
  import httpx
  from httpx_ws import aconnect_ws
  from httpx_ws.transport import ASGIWebSocketTransport
  from starlette.applications import Starlette
  from starlette.routing import WebSocketRoute
  from starlette.websockets import WebSocketDisconnect
  
  
  async def ws_hello(websocket):
      try:
          await websocket.accept()
          await websocket.send_text("Hello World!")
          await websocket.receive_text()
      except WebSocketDisconnect:
          pass
      except Exception as e:
          logging.exception(e)
  
  app = Starlette(
      routes=[
          WebSocketRoute("/ws", ws_hello),
      ],
  )
  
  async def main():
      async with httpx.AsyncClient(transport=ASGIWebSocketTransport(app)) as client:
          async with aconnect_ws("http://server/ws", client) as ws:
              message = await ws.receive_text()
              assert message == "Hello World!"
  
  asyncio.run(main())
ERROR:root:Expected ASGI message "websocket.receive" or "websocket.disconnect", but got 'websocket.close'
Traceback (most recent call last):
  File "main.py", line 16, in ws_hello
    await websocket.receive_text()
  File "\.venv\Lib\site-packages\starlette\websockets.py", line 118, in receive_text
    message = await self.receive()
              ^^^^^^^^^^^^^^^^^^^^
  File "\.venv\Lib\site-packages\starlette\websockets.py", line 49, in receive
    raise RuntimeError(
RuntimeError: Expected ASGI message "websocket.receive" or "websocket.disconnect", but got 'websocket.close'
@cfytrok cfytrok added the bug Something isn't working label Dec 26, 2024
@jamesbw
Copy link

jamesbw commented Jan 14, 2025

Same issue encountered here. I agree with @cfytrok that websocket.disconnect needs to be emitted. (thanks for the lib btw @frankie567 , super helpful).

@lulingar
Copy link

lulingar commented Feb 13, 2025

How do you work around this? I'm trying to write a pull request to fix this but I'm no expert in websockets, and I got clueless upon seeing that wsproto does not have a class for disconnect, but for close only.

Can this be done by doing a blanket replacement of "websocket.close" for "websocket.disconnect"?

@lulingar lulingar linked a pull request Feb 13, 2025 that will close this issue
@lulingar
Copy link

Please review #101.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants