New issue
Advanced search Search tips

Issue 679173 link

Starred by 1 user

Issue metadata

Status: WontFix
Owner:
Closed: Jan 2017
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux
Pri: 2
Type: Bug



Sign in to add a comment

WebSocket: try/catch for send doesn't work properly

Reported by dusel...@gmail.com, Jan 7 2017

Issue description

UserAgent: Mozilla/5.0 (X11; CrOS x86_64 8872.73.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.103 Safari/537.36

Steps to reproduce the problem:
1. Very simple scenario:
1.1. Start server
1.2. Start client
1.3. Stop server
2. Client code:
    ...
    let socket = new WebSocket('ws://' + window.location.host);
    socket.onopen = function() {
        console.log('onopen: Connected');
    };

    socket.onclose = function(event) {
        if (event.wasClean) {
            console.log('onclose: Disconnected OK');
        } else {
            console.log('onclose: Disconnected on error: ' + event.code);
        }
	try {
		socket.send('from client err');
	}
	catch (err) {
		console.log('send error: ' + err.message);
	}
        return;
    };

    socket.onmessage = function(event) {
        console.log('onmessage: ' + event.data);
		socket.send('from client');
    };

    socket.onerror = function(error) {
        console.log('onerror: ' + error.message);
    };
    try {
		socket.send('from client err');
	}
   catch (err) {
		console.log('send error: ' + err.message);
   }
  ...

What is the expected behavior?
Console log:
send error: Failed to execute 'send' on 'WebSocket': Still in CONNECTING state.
onopen: Connected
onmessage: something from server
onclose: Disconnected on error: 1006
WebSocket is already in CLOSING or CLOSED state.

What went wrong?
One of the try/catch doesn't catch the exception "WebSocket is already in CLOSING or CLOSED state."
See also: Web socket exception could not be caught - http://stackoverflow.com/questions/24786628/web-socket-exception-could-not-be-caught

Did this work before? No 

Does this work in other browsers? N/A

Chrome version: 51.0.2704.91  Channel: n/a
OS Version: Ubuntu 14.04, running on Raspbian 8.0
Flash Version: 

try/catch should not depend from the socket state.
Thanks.
 

Comment 2 by tkent@chromium.org, Jan 8 2017

Components: -Blink>JavaScript Blink>Network>WebSockets
Labels: TE-NeedsTriageHelp
Labels: Needs-Feedback
Owner: yhirano@chromium.org
The spec says: 

"
The send(data) method transmits data using the connection. If the readyState attribute is CONNECTING, it must throw an "InvalidStateError" DOMException. Otherwise, the user agent must run the appropriate set of steps from the following list:
...
"

https://html.spec.whatwg.org/multipage/comms.html#dom-websocket-send

So we are not expected to throw an exception if the readyState is CLOSING or CLOSED, right?

Comment 5 by dusel...@gmail.com, Jan 12 2017

I'm not sure that the scenario below is atomic:
1. Check readyState
2. If 1 is OK then send
It means that the state may be changed between 1 and 2, and the error will not be handled.
If you google the context "WebSocket is already in CLOSING or CLOSED state" you find how many frameworks have problems with it.
That is why ws in node.js at https://github.com/websockets/ws introduced the way to handle such errors:
---------------------------------------------------------------------
Error handling best practices

// If the WebSocket is closed before the following send is attempted
ws.send('something');

// Errors (both immediate and async write errors) can be detected in an optional
// callback. The callback is also the only way of being notified that data has
// actually been sent.
ws.send('something', function ack(error) {
  // If error is not defined, the send has been completed, otherwise the error
  // object will indicate what failed.
});

// Immediate errors can also be handled with `try...catch`, but **note** that
// since sends are inherently asynchronous, socket write failures will *not* be
// captured when this technique is used.
try { ws.send('something'); }
catch (e) { /* handle error */ }
---------------------------------------------------------------------
Regards,
LP 
IIUC incoming input from the network doesn't interrupt JS execution.

With the following code,

if (ws.readyState !== OPEN) {
  return;
}
ws.send(something);

you will not have a readyState error. I searched the web with the query. The top one (https://github.com/faye/faye/issues/371) looks fixed by the readyState check (https://github.com/faye/faye/issues/371#issuecomment-187158348).

The async interface in the node doc looks for handling async errors and that is not related to the readyState error.

Thanks,


Comment 7 by dusel...@gmail.com, Jan 13 2017

Thanks a lot,
may be closed.
LP
P.S. I'm from the interruptible world - once bitten, twice shy :-)
Status: WontFix (was: Unconfirmed)
Thanks!

Sign in to add a comment