Handling websockets module exceptions and errors

Viewed 2729

I'm trying to create a simple WebSocket server using websockets module in Python.

My task is to create a WebSocket server that sends a message to all the clients that are listening to it. The problem is that everytime a client disconnects, websockets launches an exception (ConnectionClosedOK or ConnectionClosedError, depending of what happened) that I need to catch because I have to unregister the clients that have disconnected so that the WebSocket stops to send messages in the ether (and stopping the WebSocket server throwing these exceptions everytime that he tries to send a message to a closed client).

Here's the server's code:

async def foo_call():
    await asyncio.sleep(3)
    print('Hi!')


async def register(websocket):
    users.add(websocket)
    await notify_users()


async def unregister(websocket):
    users.remove(websocket)


async def start(websocket, path):
    await register(websocket)

    try:
        await foo_call()
    except websockets.ConnectionClosedError:
        await unregister(websocket)


# WebSocket clients that are listening this WebSocket server
users = set()

# Open WebSocket server
start_server = websockets.serve(start, "localhost", 8765)

# Run asyncio event loop
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

And here's the traceback:

Task exception was never retrieved
future: <Task finished coro=<WebSocketCommonProtocol.send() done, defined at /home/vlado/Projects/dahua/venv/lib/python3.6/site-packages/websockets/protocol.py:521> exception=ConnectionClosedError('code = 1006 (connection closed abnormally [internal]), no reason',)>
Traceback (most recent call last):
  File "/home/vlado/Projects/dahua/venv/lib/python3.6/site-packages/websockets/protocol.py", line 827, in transfer_data
    message = await self.read_message()
  File "/home/vlado/Projects/dahua/venv/lib/python3.6/site-packages/websockets/protocol.py", line 895, in read_message
    frame = await self.read_data_frame(max_size=self.max_size)
  File "/home/vlado/Projects/dahua/venv/lib/python3.6/site-packages/websockets/protocol.py", line 971, in read_data_frame
    frame = await self.read_frame(max_size)
  File "/home/vlado/Projects/dahua/venv/lib/python3.6/site-packages/websockets/protocol.py", line 1051, in read_frame
    extensions=self.extensions,
  File "/home/vlado/Projects/dahua/venv/lib/python3.6/site-packages/websockets/framing.py", line 105, in read
    data = await reader(2)
  File "/usr/lib/python3.6/asyncio/streams.py", line 672, in readexactly
    raise IncompleteReadError(incomplete, n)
asyncio.streams.IncompleteReadError: 0 bytes read on a total of 2 expected bytes

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/vlado/Projects/dahua/venv/lib/python3.6/site-packages/websockets/protocol.py", line 555, in send
    await self.ensure_open()
  File "/home/vlado/Projects/dahua/venv/lib/python3.6/site-packages/websockets/protocol.py", line 803, in ensure_open
    raise self.connection_closed_exc()
websockets.exceptions.ConnectionClosedError: code = 1006 (connection closed abnormally [internal]), no reason

I don't really understand how can I catch those exceptions thrown by websockets module.

0 Answers
Related