How to force-close a websocket endpoint in on_connect without exception

I’m trying to “lock down” a websocket endpoint like so:

    async def on_connect(self, websocket: WebSocket) -> None:
        if not websocket.user.is_authenticated and not self.allow_anonymous:
            await websocket.close(status.WS_1008_POLICY_VIOLATION)
            log.warning(f"unauthenticated connection attempt")
            return
        await super().on_connect(websocket)

Starlette completes the close, client gets a 403 status, but after exiting the on_disconnect I get this exception:

 File "/home/rod/Projects/tailored-labs/emotive_chat/manage.py", line 20, in <module>
  main()
 File "/home/rod/Projects/tailored-labs/emotive_chat/manage.py", line 14, in main
  uvicorn.run(app, host='0.0.0.0', port=8000)
File "/home/rod/.local/share/virtualenvs/emotive_chat-sxd5cU2a/lib/python3.7/site-packages/uvicorn/main.py", line 279, in run
  server.run()
File "/home/rod/.local/share/virtualenvs/emotive_chat-sxd5cU2a/lib/python3.7/site-packages/uvicorn/main.py", line 307, in run
  loop.run_until_complete(self.serve(sockets=sockets))
File "/home/rod/.local/share/virtualenvs/emotive_chat-sxd5cU2a/lib/python3.7/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 156, in run_asgi
  self.logger.error(msg, exc_info=exc)
File "/home/rod/.pyenv/versions/3.7.3/lib/python3.7/logging/__init__.py", line 67, in error
File "/home/rod/.pyenv/versions/3.7.3/lib/python3.7/logging/__init__.py", line 1820, in _LogErrorReplacement
  logger = self.logger
File "/home/rod/.local/share/virtualenvs/emotive_chat-sxd5cU2a/lib/python3.7/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 152, in run_asgi
  result = await self.app(self.scope, self.asgi_receive, self.asgi_send)
File "/home/rod/.local/share/virtualenvs/emotive_chat-sxd5cU2a/lib/python3.7/site-packages/starlette/applications.py", line 134, in __call__
  await self.error_middleware(scope, receive, send)
File "/home/rod/.local/share/virtualenvs/emotive_chat-sxd5cU2a/lib/python3.7/site-packages/starlette/middleware/errors.py", line 143, in __call__
  await self.app(scope, receive, send)
File "/home/rod/.local/share/virtualenvs/emotive_chat-sxd5cU2a/lib/python3.7/site-packages/starlette/middleware/authentication.py", line 48, in __call__
  await self.app(scope, receive, send)
File "/home/rod/.local/share/virtualenvs/emotive_chat-sxd5cU2a/lib/python3.7/site-packages/starlette/exceptions.py", line 53, in __call__
  await self.app(scope, receive, send)
File "/home/rod/.local/share/virtualenvs/emotive_chat-sxd5cU2a/lib/python3.7/site-packages/starlette/routing.py", line 590, in __call__
  await route(scope, receive, send)
File "/home/rod/.local/share/virtualenvs/emotive_chat-sxd5cU2a/lib/python3.7/site-packages/starlette/routing.py", line 352, in __call__
  await self.app(scope, receive, send)
File "/home/rod/.local/share/virtualenvs/emotive_chat-sxd5cU2a/lib/python3.7/site-packages/starlette/routing.py", line 590, in __call__
  await route(scope, receive, send)
File "/home/rod/.local/share/virtualenvs/emotive_chat-sxd5cU2a/lib/python3.7/site-packages/starlette/routing.py", line 352, in __call__
  await self.app(scope, receive, send)
File "/home/rod/.local/share/virtualenvs/emotive_chat-sxd5cU2a/lib/python3.7/site-packages/starlette/routing.py", line 590, in __call__
  await route(scope, receive, send)
File "/home/rod/.local/share/virtualenvs/emotive_chat-sxd5cU2a/lib/python3.7/site-packages/starlette/routing.py", line 264, in __call__
  await self.app(scope, receive, send)
File "/home/rod/.local/share/virtualenvs/emotive_chat-sxd5cU2a/lib/python3.7/site-packages/starlette/endpoints.py", line 74, in dispatch
  raise exc from None
File "/home/rod/.local/share/virtualenvs/emotive_chat-sxd5cU2a/lib/python3.7/site-packages/starlette/endpoints.py", line 65, in dispatch
  message = await websocket.receive()
File "/home/rod/.local/share/virtualenvs/emotive_chat-sxd5cU2a/lib/python3.7/site-packages/starlette/websockets.py", line 40, in receive
  message = await self._receive()
File "/home/rod/.local/share/virtualenvs/emotive_chat-sxd5cU2a/lib/python3.7/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 232, in asgi_receive
  data = await self.recv()
File "/home/rod/.local/share/virtualenvs/emotive_chat-sxd5cU2a/lib/python3.7/site-packages/websockets/protocol.py", line 470, in recv
  return_when=asyncio.FIRST_COMPLETED,
File "/home/rod/.pyenv/versions/3.7.3/lib/python3.7/asyncio/tasks.py", line 361, in wait
  fs = {ensure_future(f, loop=loop) for f in set(fs)}
File "/home/rod/.pyenv/versions/3.7.3/lib/python3.7/asyncio/tasks.py", line 361, in <setcomp>
  fs = {ensure_future(f, loop=loop) for f in set(fs)}
File "/home/rod/.pyenv/versions/3.7.3/lib/python3.7/asyncio/tasks.py", line 592, in ensure_future
  raise TypeError('An asyncio.Future, a coroutine or an awaitable is '

builtins.TypeError: An asyncio.Future, a coroutine or an awaitable is required

Hi @rmorison! Welcome to these forums. :smiley: I think you might be better off opening an issue on the Starlette repository for this, as this is potentially a bug: https://github.com/encode/starlette/issues. Be sure to include a small reproduction example so that people can try and reproduce the issue (from the above it isn’t obvious to me whether the issue comes from Starlette, the websockets library, or your particular setup).

Done, Thanks. Big fan of Tom’s work, btw. :grinning: