Stardaz
Stardaz

Reputation: 15

Unable to catch asyncio.IncompleteReadError for websocket server

I am currently working on a websocket server to allow communication between 2 computers, and I'm coding the communication between PC and server. I made a command to stop the server remotely, but when the connection is lost the script doesn't stop, I want to fix that. The code:

try:
    #Allow to receive mutliple messages from server
    while True:
        response = await asyncio.wait_for(websocket.recv(), timeout=1)
        print(color + response + colorama.Style.RESET_ALL)
except asyncio.TimeoutError:
    print("No response from server")
    if must_restart == True:
        return 'restart'
except asyncio.IncompleteReadError:
    print("Incomplete read, connection might be closed")
    return
except websockets.exceptions.ConnectionClosedError:
    print("Connection closed")
    return

When running in debug mode (otherwise I don't get it), I get this exception :

asyncio.exceptions.IncompleteReadError: 0 bytes read on a total of 2 expected bytes

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

  File "C:\Users\stard\OneDrive\Documents\code\Coomunication\com.py", line 131, in send_message
    response = await asyncio.wait_for(websocket.recv(), timeout=1)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\stard\OneDrive\Documents\code\Coomunication\com.py", line 257, in Client
    result = await send_message(list(machines.keys())[sel],list(machines.items())[sel][1])
  File "C:\Users\stard\OneDrive\Documents\code\Coomunication\com.py", line 291, in <module>
    asyncio.run(Client())
websockets.exceptions.ConnectionClosedError: no close frame received or sent

I put an except.IncompleteReadError: so why isn't the exception caught? Is this beacuse of asyncio.wait_for? If it is, what is the solution?

Upvotes: 0

Views: 32

Answers (1)

VPfB
VPfB

Reputation: 17342

The traceback shows that the websocket module has caught the IncompleteReadError and reacted to it by raising the ConnectionClosedError exception.

So, the exception actually raised was is the ConnectionClosedError and this is the exception type you should catch in an except. The caught exception has a __cause__ or __context__ attribute that points to the IncompleteReadError error that was the primary cause of exception handling. It is called "a chained exception".

In the except clause you could check if the type of chained exception is what you want to handle, but if the exception chaining is not documented, it may behave differently in future versions.

More info here: https://docs.python.org/3/library/exceptions.html#exception-context

Upvotes: 1

Related Questions