80

Let's say I have a node server started with port nn, and there is not any WebSocket service on it.

And the problem is that my client trys to connect a WebSocket service to this server.

Obviously, it should fail to connect to the server.

But I couldn't catch this error, my client code is the following:

try {
    this.ws = new WebSocket('ws://xxx:nn');
} catch ( e ) {
    fallback();
    console.warn(e);
}

My expectation is that the fallback method gets called while connecting fails, but actually the error is not caught by the above try...catch

Does anyone know how to catch the error in my usecase?

Jake Thakur
  • 156
  • 3
  • 10
Howard
  • 4,474
  • 6
  • 29
  • 42
  • 6
    Did you end up finding a solution for this? – orange Jun 12 '15 at 07:23
  • 5
    Possible duplicate of [Javascript doesn't catch error in WebSocket instantiation](http://stackoverflow.com/questions/31002592/javascript-doesnt-catch-error-in-websocket-instantiation) – Eliran Malka Apr 27 '16 at 14:07
  • in answer that EliranMalka mentioned, stated that this error could not be catched, becasue it is async emitted and not thrown – bFunc Aug 16 '19 at 21:05
  • A Promise version of Websocket is needed so the error can be asynchronously caught in the Promise's catch block rather than forcibly output to the console like it is now. – Jonathan Nov 25 '22 at 08:55

4 Answers4

21

You can register for onError callback of websocket object

exampleSocket.onerror=function(event){
    console.log("Error");
}

You can refer following example. http://jsfiddle.net/g28yuymv/1/

catching error example http://jsfiddle.net/g28yuymv/4/

shivakumar
  • 3,297
  • 19
  • 28
  • 9
    This won't work, i tried. My case is i have a server running on port `nn` , but there is no any webSocket service on it. While the client try to connect this server by using websocket, the error is thrown, and neither `try..catch` nor `onerror` could not catch this exception – Howard Sep 11 '14 at 08:10
  • 2
    OK @Howard.In my example (http://jsfiddle.net/g28yuymv/10/) I'm able to get onError event if there is no WS service running on requested port.If you have hosted any WS service on any public cloud let me know the test url. According to me you are hitting "500 internal server error" behavior. – shivakumar Sep 11 '14 at 12:34
  • Thanks. I can do more test for this behaviour – Howard Sep 12 '14 at 04:12
  • 18
    This is correct; an event handler such as above does get executed when the connection error occurs. The reason it may **look** like the error doesn't get handled is because the glaring red error text is still logged to the console, even if you handled it here. To my knowledge there is not yet any way to stop the glaring red error text. – JMTyler Mar 30 '16 at 21:44
  • This captures the error but does not catch it, as I would expect with a try/catch block. – Miki Jul 20 '21 at 19:14
  • 1
    This is a fired error event on the socket object rather than an actual thrown error object. In the case of connection error in chrome, the error event contains no useful information such as an error message, all we know is that some error occurred on the websocket. – Phil Sep 08 '22 at 21:06
  • @Phil is right, I'm facing the same problem. The onerror handler of the WebSocket receives an event object. That event objects has type="error", it does not tell anything specific about the error. Although a useful error message appears in the console log ("Websocket connection to ..... failed), this error message seems to be inaccessible from JavaScript. – nagylzs Oct 29 '22 at 19:34
  • There is only one error that can happen during a Websocket constructor, and that's if it cannot establish a connection to the URL it's being built for. Just like `Image` or `Video` etc will trigger their `error` event if the URL you give them doesn't work, a WebSocket will do the same. You don't get the reason, you just get the _signal_, just like for `Image`, `Video`, etc. If the reason matters, run a `fetch` request to the websocket URL first in order to verify that it exists, has the right headers, etc, and only _then_ create your websocket. – Mike 'Pomax' Kamermans Mar 12 '23 at 17:18
  • (note: just like for `Image` and `Video`, the error just says "I cannot create this thing that you need me to create, based on the values you told me to use", so the URL might not exist, or it might exist but serve the wrong data, or serve the correct data but die halfway through the transmission, etc. etc. the only signal you get from the WebSocket itself is that "something went wrong as part of me trying to negotiate a socket connection", just like how `Image` will not tell you whether the URL is a 404, or serving HTML instead of an image, or the image data is corrupted, etc. etc) – Mike 'Pomax' Kamermans Mar 12 '23 at 17:29
13

Looking at the HTML5 WebSockets spec, you can pass a value into the close() method. Then on the onclose() event listener you can check against that value. This gives you the opportunity to set handlers for different disconnect scenarios and then handle everything else as a generic error.

https://developer.mozilla.org/en-US/docs/Web/API/WebSocket#close()

var _websocket;

function wsConnect() {
  if (_websocket) {
    _websocket.close(3001);
  } else {
    _websocket = new WebSocket("wss://echo.websocket.org1");
    _websocket.onopen = function() {
      console.log('connected');
    };
    _websocket.onmessage = function(msg) {
      console.log(msg);
    };

    _websocket.onclose = function(evt) {
      if (evt.code == 3001) {
        console.log('ws closed');
        _websocket = null;
      } else {
        _websocket = null;
        console.log('ws connection error');
      }
    };

    _websocket.onerror = function(evt) {
      if (_websocket.readyState == 1) {
        console.log('ws normal error: ' + evt.type);
      }
    };
  }
}

wsConnect();

sweet fiddle: https://jsfiddle.net/lamarant/ry0ty52n/

lamarant
  • 3,243
  • 2
  • 25
  • 30
  • I wanted to catch the ECONREFUSED error whenever my script tried to reconnect to the websocket server, above code works perfectly, it saved my nodejs script from crashing during the reconnect. – Jayant May 19 '16 at 11:26
2

the above answers cannot be correct. You want to treat it as an error. But that message is more of a warning/info that shows when the following happens.

WebSocketTransport.prototype.close = function() {
  debug('close');
  var ws = this.ws;
  this._cleanup();
  if (ws) {
    ws.close();
  }
};

correct should be:

exampleSocket.onclose = async (event) => {
        console.error(event);    
//do what you want
}
-3

readyState property sets to 1 when connection is successful hence it can be used to determine the connection state , socket connection usually takes < 1 sec , so we can safely take 3 sec gap and then check the connection state.

Following is the code :

this.ws = new WebSocket('ws://xxx:nn');

setTimeout(() => {
   if (this.ws.readyState !== 1) {
       alert("Problem connection , kindly contact system admin .");
   }
}, 3000);
Simon
  • 2,686
  • 2
  • 31
  • 43
Mr Coder
  • 8,169
  • 5
  • 45
  • 74
  • Please add an explanation of your code to your answer. – rgettman May 19 '15 at 18:56
  • 2
    It's not safe to assume a 3-second timeout because poor connections (e.g. mobile phones) or slow servers can easily take longer than 3-seconds. Need to also consider if the readyState is connecting `readyState === 0` before determining a problem exists. – thesmart Mar 29 '21 at 04:25