question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Implement catchable WebsocketClosed

See original GitHub issue

See #2220

In v21.9, a new WebsocketClosed exception was added.

While you can to do the following:

@app.websocker("/")
async def handler(request, ws):
    try:
        ...
    except asyncio.CancelledError:
        print("connection closed")

We would like to add support for this pattern:

@app.websocker("/")
async def handler(request, ws):
    try:
        ...
    except sanic.exceptions.WebsocketClosed:
        print("connection closed")

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:9 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
ashleysommercommented, Oct 3, 2021

@ahopkins I think there might’ve been some miscommunication around what the WebsocketClosed exception is for.

In #2248, WebsocketsClosed exception was added as a replacement for throwing sanic.ServerError exceptions if a user tries to read or write to a websocket connection that is closed or is closing. This also prevented the KeepAlive-ping background task from emitting a ServerError needlessly when the websocket connection was closed.

In theory (if the timing it right) it is possible to catch it like this:

@app.websocker("/")
async def handler(request, ws):
    try:
        while(True):
            ws.write("hello") # <-- this could throw WebsocketClosed when the socket closes
    except sanic.exceptions.WebsocketClosed:
        print("connection closed")

However also in #2248, I introduced more capability for the websockets connection to raise asyncio.CancelledError into the handler, to give the handler early warning that the connection is closing, and prevent the handler from continuing to make send() and recv() calls. So this change significantly decreases the possibility of the handler seeing a WebsocketClosed exception, because it would see asyncio.CancelledError first, and break from its handling.

If we really want the ability to catch a websocket-specific exception, rather than asyncio.CancelledError, then I suggest we create a new exception like WebsocketCancelled that subclasses asyncio.CancelledError, and use that instead.

Then the handler could use code like this to cover both:

@app.websocker("/")
async def handler(request, ws):
    try:
        ...
    except (WebsocketClosed, WebsocketCancelled)
        print("connection closed")
0reactions
ahopkinscommented, Aug 28, 2022
Read more comments on GitHub >

github_iconTop Results From Across the Web

WebSocket.close() - Web APIs - MDN Web Docs
close() method closes the WebSocket connection or connection attempt, if any. If the connection is already CLOSED , this method does nothing.
Read more >
Uncatchable error for close message of 123 bytes ... - GitHub
Description. If the other side has a problem and closes the websocket-connection with an message this message must not be greater than 123...
Read more >
javascript - How to catch and deal with "WebSocket is already ...
The easiest way is to check if the socket is open or not before sending. For example - write a simple function: function...
Read more >
WebSockets - Closing a Connection - Tutorialspoint
WebSockets - Closing a Connection, Close event marks the end of a communication between the server and the client. Closing a connection is...
Read more >
How to Close a WebSocket (Correctly) - Forty Years of Code
A client WebSocket that starts the closing handshake fails to transition to the Closed state when the server acknowledges the initial Close ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found