I am making a ws connection, but in some cases I need/want to abort the request cleanly, without the console logging an error like this one -
WebSocket connection to 'ws://xyz:3001/? failed: WebSocket is closed before the connection is established.
the code looks like:
const ws = new WebSocket(`${url}`);
setTimeout(() => ws.close(), random); // some other event that occur at any given time "random"
A simple use case is if a connection is initiated when a user opens a view, but then quickly closes the view which could/should abort the connection request.
is there a way to abort the connection request cleanly, so that I don't get too many logs like that in the browser console?
You can test and see if the
readyStateproperty could help.You can use it to check the connection's current state before attempting to close it. That would allow you to avoid trying to close the connection if it is not in an open state, thus preventing the error message from appearing in the console.
The WebSocket API provides different states through the
readyStateattribute:CONNECTING(0): The connection is not yet open.OPEN(1): The connection is open and ready to communicate.CLOSING(2): The connection is in the process of closing.CLOSED(3): The connection is closed or could not be opened.You can use these states to decide when it is appropriate to close the WebSocket:
That code modification makes sure
ws.close()is only called if the WebSocket is either still connecting or already open. If the WebSocket is in the process of closing or is already closed, callingclose()again can lead to unwanted errors or logs.Given the limitations of the WebSocket API in handling this specific use case directly, you might consider using a flag to prevent actions on early closure.
Or you could delay the actual connection attempt until you are more certain you will need it. That could involve setting up a preliminary delay (debouncing the connection attempt, as previously discussed) to make sure the user's action necessitates the WebSocket connection:
That also ties in with the OP's
whatwg/websocketsissue 57, where Adam Rice (ricea), from the Chromium project, adds:So the
signal.throwIfAborted()call will make sure that, if the operation was already aborted before the WebSocket connection was initiated, it would immediately throw, preventing the connection.If the abort event is signaled after the connection attempt has started but before it is fully open, it calls
ws.close()to terminate the attempt. Once the connection is successfully opened, it removes the abort event listener to clean up resources.But, as noted by Bergi in the comments, using
ws.close()to terminate a WebSocket connection attempt that has not fully opened could still lead to a warning in the developer console.That is precisely the situation you were aiming to avoid, as the goal is to abort the connection attempt silently, without generating console warnings.
You might consider a slightly different approach, focusing on preventing the connection attempt from proceeding or being initiated based on the abort signal, rather than trying to close an already initiated connection.
However, this approach has limitations because, once a WebSocket connection attempt is made, the API does not provide a built-in, silent abort mechanism.
You can modify Adam Rice's code to integrate the abort logic in a way that minimizes the chances of generating console warnings. You woud introduce a check before initiating the WebSocket connection to make sure the abort signal has not been triggered. And modify the cleanup process to make sure resources are released without necessarily closing the WebSocket connection if it is still in the
CONNECTINGstate.Instead of closing the WebSocket upon abort, manage the state to prevent further actions on the WebSocket if it is not yet open.