Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uncaught, unspecified "error" event. #246

Closed
seelnolu opened this issue Sep 30, 2013 · 28 comments
Closed

Uncaught, unspecified "error" event. #246

seelnolu opened this issue Sep 30, 2013 · 28 comments

Comments

@seelnolu
Copy link

I received this error:

events.js:74
        throw TypeError('Uncaught, unspecified "error" event.');
              ^
TypeError: Uncaught, unspecified "error" event.
    at TypeError (<anonymous>)
    at WebSocket.EventEmitter.emit (events.js:74:15)
    at Receiver.self._receiver.onerror (/opt/ws-server-v2/node_modules/ws/lib/WebSocket.js:719:10)
    at Receiver.error (/opt/ws-server-v2/node_modules/ws/lib/Receiver.js:301:8)
    at Receiver.processPacket (/opt/ws-server-v2/node_modules/ws/lib/Receiver.js:187:10)                                                                                                                     
    at Receiver.add (/opt/ws-server-v2/node_modules/ws/lib/Receiver.js:93:24)
    at CleartextStream.firstHandler (/opt/ws-server-v2/node_modules/ws/lib/WebSocket.js:678:22)
    at CleartextStream.EventEmitter.emit (events.js:95:17)
    at CleartextStream.<anonymous> (_stream_readable.js:746:14)
    at CleartextStream.EventEmitter.emit (events.js:92:17)

Node-ws-server seems to run for up to 1 to 48 hours, then I receive that error stated above. I am not sure what is happend. Or if the the packet being sent over web-socket is corrupt or some thing else. What should I do to fix this error?

  • node - v0.10.17
  • ws - v0.4.30
  • express - v3.4.0

websocket code:

var WebSocketServer = require('ws').Server;

// Create server
var httpServ = (config.webSocket.ssl) ? require('https') : require('http'),
    fs = require('fs'),
    app = null;

if (config.webSocket.ssl) {
    app = httpServ.createServer({
        // providing server with  SSL key/cert & other options
        key: fs.readFileSync(config.webSocket.ssl_key),
        cert: fs.readFileSync(config.webSocket.ssl_cert),
        ca: fs.readFileSync(config.webSocket.ssl_ca),
        requestCert: config.webSocket.requestCert,
        rejectUnauthorized: config.webSocket.rejectUnauthorized
    }, api.processRequest).listen(config.webSocket.port);
} else {
    app = httpServ.createServer(api.processRequest).listen(config.webSocket.port);
}

// passing or reference to web server so WS would knew port and SSL capabilities
var wss = new WebSocketServer({ server:app });

wss.on('connection', function (ws) {

    function onWsMessage(message) {
        ...
    }

    function onWsClose() {
        socket.close(ws);
        delete ws;
    }

    function onWsError(e) {
        console.error('Client #%d error: %s', ws.id, e.message);
    }

    ws.on('message', onWsMessage);
    ws.on('close', onWsClose);
    ws.on('error', onWsError);
});

logger.log("Server started on port " + config.webSocket.port);
@qwerter
Copy link

qwerter commented Nov 8, 2013

I'm getting same error when using certain browsers, huh!

@3rd-Eden
Copy link
Member

3rd-Eden commented Nov 8, 2013

And what "certain" browsers are talking about? Does this mean you have a reproducible test case?

@qwerter
Copy link

qwerter commented Nov 8, 2013

opera 12.16

@qwerter
Copy link

qwerter commented Nov 8, 2013

it happens every time with opera, not sure why

@3rd-Eden
Copy link
Member

3rd-Eden commented Dec 3, 2013

What are you guys sendings over the WebSocket connection? are they small chunks of data, rapid chunks, large chunks of data, binary? Any insight would be welcome.

@qwerter
Copy link

qwerter commented Dec 3, 2013

well, i am sending raw pcm audio chunks (binary data), chunks are not too big (up to 100kb) at 1 second interval

@qwerter
Copy link

qwerter commented Dec 3, 2013

but it crashes before sending starts, will try to debug it tonight and will give you more details about what's happening

@3rd-Eden
Copy link
Member

3rd-Eden commented Dec 3, 2013

@ktor9 I think i've discovered at least one small race condition in this; I've committed a potential fix it here: https://github.com/einaros/ws/tree/error-before-close

What i've been seeing is that the receiver.onerror handler closes the connection before it's an error event. The close methods cleans up some resources and calls the .terminate method of the WebSocket which will do more aggressive cleaning which includes removing all assigned EventListeners.

So emitting the error before we close the connection might solve the thrown error as we see above. But that doesn't solve the actual reason why you received the error in the first place. And that is because it recieved an unexpected continuation frame from the browser client as seen on: https://github.com/einaros/ws/blob/master/lib/Receiver.js#L198 so either the browser is sending the wrong frames or we are setting the wrong opcode state internally in the receiver.

Btw, what platform are you running on? Linux, Windows, Mac OSX?

@julien-f
Copy link
Contributor

Same error here with Safari 5.0.5 on MacOS.

As far as I can tell it happens during the connection or shortly after (within seconds).

Using your branch does not fix the error but I do get a longer stacktrace:

events.js:74
        throw TypeError('Uncaught, unspecified "error" event.');
              ^
TypeError: Uncaught, unspecified "error" event.
    at TypeError (<anonymous>)
    at WebSocket.EventEmitter.emit (events.js:74:15)
    at Receiver.self._receiver.onerror (/root/xo/xo-server/node_modules/ws/lib/WebSocket.js:717:10)
    at Receiver.error (/root/xo/xo-server/node_modules/ws/lib/Receiver.hixie.js:153:8)
    at doAdd (/root/xo/xo-server/node_modules/ws/lib/Receiver.hixie.js:61:14)
    at Receiver.add (/root/xo/xo-server/node_modules/ws/lib/Receiver.hixie.js:104:22)
    at CleartextStream.firstHandler (/root/xo/xo-server/node_modules/ws/lib/WebSocket.js:678:22)
    at CleartextStream.EventEmitter.emit (events.js:95:17)
    at CleartextStream.<anonymous> (_stream_readable.js:736:14)
    at CleartextStream.EventEmitter.emit (events.js:92:17)
    at emitDataEvents (_stream_readable.js:761:10)
    at CleartextStream.Readable.on (_stream_readable.js:682:5)
    at WebSocket.establishConnection (/root/xo/xo-server/node_modules/ws/lib/WebSocket.js:733:10)
    at WebSocket.initAsServerClient (/root/xo/xo-server/node_modules/ws/lib/WebSocket.js:453:72)
    at new WebSocket (/root/xo/xo-server/node_modules/ws/lib/WebSocket.js:63:24)
    at /root/xo/xo-server/node_modules/ws/lib/WebSocketServer.js:367:24
    at afterWrite (_stream_writable.js:270:3)
    at _stream_writable.js:259:9
    at process._tickCallback (node.js:415:13)
    at CleartextStream.Readable.on (_stream_readable.js:679:33)
    at WebSocket.establishConnection (/root/xo/xo-server/node_modules/ws/lib/WebSocket.js:733:10)
    at WebSocket.initAsServerClient (/root/xo/xo-server/node_modules/ws/lib/WebSocket.js:453:72)
    at new WebSocket (/root/xo/xo-server/node_modules/ws/lib/WebSocket.js:63:24)
    at /root/xo/xo-server/node_modules/ws/lib/WebSocketServer.js:367:24
    at afterWrite (_stream_writable.js:270:3)
    at _stream_writable.js:259:9
    at process._tickCallback (node.js:415:13)
    at onwrite (_stream_writable.js:258:15)
    at WritableState.onwrite (_stream_writable.js:97:5)
    at CleartextStream.write [as _write] (tls.js:388:9)
    at doWrite (_stream_writable.js:219:10)
    at writeOrBuffer (_stream_writable.js:209:5)
    at CleartextStream.Writable.write (_stream_writable.js:180:11)
    at WebSocketServer.completeHandshake (/root/xo/xo-server/node_modules/ws/lib/WebSocketServer.js:365:16)
    at onClientVerified (/root/xo/xo-server/node_modules/ws/lib/WebSocketServer.js:397:25)
    at WebSocketServer.handleHixieUpgrade (/root/xo/xo-server/node_modules/ws/lib/WebSocketServer.js:443:3)
    at WebSocketServer.handleUpgrade (/root/xo/xo-server/node_modules/ws/lib/WebSocketServer.js:146:61)
    at $WebServer.<anonymous> (/root/xo/xo-server/node_modules/ws/lib/WebSocketServer.js:72:12)
    at $WebServer.EventEmitter.emit (events.js:106:17)
    at Server.<anonymous> (/root/xo/xo-server/src/web-server.coffee:100:33)
    at Server.EventEmitter.emit (events.js:106:17)
    at CleartextStream.socket.ondata (http.js:1966:14)
    at CleartextStream.read [as _read] (tls.js:502:12)
    at CleartextStream.Readable.read (_stream_readable.js:320:10)
    at EncryptedStream.write [as _write] (tls.js:366:25)
    at doWrite (_stream_writable.js:219:10)
    at writeOrBuffer (_stream_writable.js:209:5)
    at EncryptedStream.Writable.write (_stream_writable.js:180:11)
    at write (_stream_readable.js:573:24)
    at flow (_stream_readable.js:582:7)
    at Socket.pipeOnReadable (_stream_readable.js:614:5)
    at Socket.EventEmitter.emit (events.js:92:17)
    at emitReadable_ (_stream_readable.js:408:10)
    at emitReadable (_stream_readable.js:404:5)
    at readableAddChunk (_stream_readable.js:165:9)
    at Socket.Readable.push (_stream_readable.js:127:10)
    at TCP.onread (net.js:526:21)

@vieira
Copy link

vieira commented May 18, 2014

Hello, I'm also experiencing this problem. It is not easy to reproduce but I know it happened shortly after the connection was established as the client sends a message onopen and this message was not received. The log follows but unfortunately I don't think it adds much 😫

events.js:74
        throw TypeError('Uncaught, unspecified "error" event.');
              ^
TypeError: Uncaught, unspecified "error" event.
    at TypeError (<anonymous>)
    at WebSocket.EventEmitter.emit (events.js:74:15)
    at Receiver.self._receiver.onerror (<proj>/node_modules/ws/lib/WebSocket.js:719:10)
    at Receiver.error (<proj>/node_modules/ws/lib/Receiver.js:301:8)
    at Receiver.processPacket (<proj>/node_modules/ws/lib/Receiver.js:187:10)
    at Receiver.add (<proj>/node_modules/ws/lib/Receiver.js:93:24)
    at Socket.firstHandler (<proj>/node_modules/ws/lib/WebSocket.js:678:22)
    at Socket.EventEmitter.emit (events.js:95:17)
    at Socket.<anonymous> (_stream_readable.js:746:14)
    at Socket.EventEmitter.emit (events.js:92:17)

@flowersinthesand
Copy link

Any update or workaround on this?

@3rd-Eden
Copy link
Member

@jeremyBanks that's because you're missing error listeners? So ofcourse it's going to throw if you don't have any listeners assigned. it's how node works, no error listener? error? it will throw.

@banksJeremy
Copy link

@3rd-Eden Please ignore my newbish stupidity. Thanks for the clarification.

@samsonradu
Copy link

@3rd-Eden Please mind my noobish question but I didn't get where should one attach the error listener. The below code still throws the error:

var socketServer = new (require('ws').Server)({port: WEBSOCKET_PORT});
socketServer.on('connection', function(socket) {
   socket.on('error', function(err){
            console.log(err)
        });
  ...
});

@cklokmose
Copy link

I am getting this error (or a similar error) as well.
It happens when a browser on the outside network tries to access my node service and establish a websocket connection through our loadbalancer that is not yet setup to handle websockets. I don't seem to be able to catch the error.

events.js:74
        throw TypeError('Uncaught, unspecified "error" event.');
              ^
TypeError: Uncaught, unspecified "error" event.
  at TypeError (<anonymous>:null:null)
  at WebSocket.EventEmitter.emit (events.js:74:15)
  at Receiver.self._receiver.onerror (/home/clemens/Webstrate/node_modules/ws/lib/WebSocket.js:704:10)
  at Receiver.error (/home/clemens/Webstrate/node_modules/ws/lib/Receiver.js:295:8)
  at Receiver.processPacket (/home/clemens/Webstrate/node_modules/ws/lib/Receiver.js:181:10)
  at Receiver.add (/home/clemens/Webstrate/node_modules/ws/lib/Receiver.js:87:24)
  at Socket.firstHandler (/home/clemens/Webstrate/node_modules/ws/lib/WebSocket.js:663:22)
  at Socket.EventEmitter.emit (events.js:95:17)
  at Socket.<anonymous> (_stream_readable.js:746:14)
  at Socket.EventEmitter.emit (events.js:92:17)
  at emitReadable_ (_stream_readable.js:408:10)
  at emitReadable (_stream_readable.js:404:5)
  at readableAddChunk (_stream_readable.js:165:9)
  at Socket.Readable.push (_stream_readable.js:127:10)
  at TCP.onread (net.js:526:21)

@Dragonight
Copy link

Information and solution

This error still happens on the latest version as of today (2014/11/1).

Stack trace:

events.js:74
        throw TypeError('Uncaught, unspecified "error" event.');
              ^
TypeError: Uncaught, unspecified "error" event.
    at TypeError (<anonymous>)
    at WebSocket.EventEmitter.emit (events.js:74:15)
    at Receiver.self._receiver.onerror (###/node_modules/ws/lib/WebSocket
.js:704:10)
    at Receiver.error (###/node_modules/ws/lib/Receiver.hixie.js:153:8)
    at doAdd (###/node_modules/ws/lib/Receiver.hixie.js:61:14)
    at Receiver.add (/###/node_modules/ws/lib/Receiver.hixie.js:104:22)
    at CleartextStream.firstHandler (###/node_modules/ws/lib/WebSocket.js
:663:22)
    at CleartextStream.EventEmitter.emit (events.js:95:17)
    at CleartextStream.<anonymous> (_stream_readable.js:736:14)
    at CleartextStream.EventEmitter.emit (events.js:92:17)

Reason:
When Hixie protocol is used, together with some invalid data from a crappy browser or bad protocol implementation at client side or evil user who sent bad data on purpose to crash you or any other reason. (started to happen to me when i added wss:// (https server) option in production)
This line will fire an error event:
node_modules/ws//lib/Receiver.hixie.js : 61

      if (data[0] !== 0x00) {
        self.error('payload must start with 0x00 byte', true);
        return;
      }

However, it happens when creating the connection, before the 'connection' fired.
That means we did not have any chance to attach on('error') event handler yet.
So... according to nodejs' EventEmitter:

When an EventEmitter instance experiences an error, the typical action is to emit an 'error' event.
Error events are treated as a special case in node. If there is no listener for it,
then the default action is to print a stack trace and exit the program.

( Source: http://nodejs.org/api/events.html#events_class_events_eventemitter )
Which is why the whole server crash if error event happens when initializing a connection.

However, because we don't have any access to the new Websocket instance before connection initialized to attach the error listener. I had to modify the library's code itself to fix it !!!!
I know this is a very bad solution and not future proof (but hey it works!) and this is why I am posting it here, so you can understand the problem and make a better fix for the next version of ws.

Solution (Hack): node_modules/ws//lib/WebSocket.js:55

function WebSocket(address, protocols, options) {

  if (protocols && !Array.isArray(protocols) && 'object' == typeof protocols) {
    // accept the "options" Object as the 2nd argument
    options = protocols;
    protocols = null;
  }
  if ('string' == typeof protocols) {
    protocols = [ protocols ];
  }
  if (!Array.isArray(protocols)) {
    protocols = [];
  }
  // TODO: actually handle the `Sub-Protocols` part of the WebSocket client

  this._socket = null;
  this.bytesReceived = 0;
  this.readyState = null;
  this.supports = {};

  // ######### Added by DN at 2014/11/1: to fix a crash if error event happens before 'connection' event fired, we didn't have any chance to set error handler yet
  this.on('error', function(a,b) {console.error('[WebSocket Error!]',a,b)})
  // ######### Add End ######

  if (Array.isArray(address)) {
    initAsServerClient.apply(this, address.concat(options));
  } else {
    initAsClient.apply(this, [address, protocols, options]);
  }
}

Reproduce:
Change Receiver.hixie.js:61 to make the error event always fire even on good data, and use Hixie protocol so the program will reach this line. (or find that one specific browser version that sends invalid data)

@flowersinthesand
Copy link

@Dragonight Great!

@Dragonight
Copy link

Continue - After rolling out my fix in production, my logs showed a few more errors, not only the one that I wrote about above. So you need to fix the general case, not the specific case that I wrote about.
My hack caught all of the uncaught errors that happened during connection establishing (before we had any chance to attach an error listener outside of the library's code).
After the fix my servers did not crash anymore, instead they are printing these lines the to log.
(Every line means that the server was saved from a crash^^)

[WebSocket Error!] payload must start with 0x00 byte true
[WebSocket Error!] payload must start with 0x00 byte true
[WebSocket Error!] payload must start with 0x00 byte true
[WebSocket Error!] payload must start with 0x00 byte true
[WebSocket Error!] no handler for opcode 12 1002
[WebSocket Error!] reserved fields must be empty 1002
[WebSocket Error!] payload must start with 0x00 byte true
[WebSocket Error!] payload must start with 0x00 byte true
[WebSocket Error!] payload must start with 0x00 byte true
[WebSocket Error!] payload must start with 0x00 byte true
[WebSocket Error!] reserved fields must be empty 1002

I don't know which client is sending the bad data. It started to happen only after I added wss (https) option, so I guess maybe that's have something with wss (websocket secure) that is generating invalid data on a very specific configuration of 1 user (all of other users don't have any problems).

So let's assume that an evil person writes a simple script that is sending the right invalid data on purpose to make you crash! - So he can crash any nodejs server that runs "ws" for websockets !!!
It is very likely to happen now that I posted the exact information of the bug in public... hey I might even do it too... so you should patch it immediately and update all your servers.

This bug reported 1 year ago, so I guess all current production servers who use "ws" are vulnerable.
I am not sure how to fix it in the right way, I hope someone who knows the code of "ws" in a deep level will create a good commit from my information - please let them know somehow.
CRITICAL BUG

Thanks,

  • DN

@thereals0beit
Copy link

s0beit@ubuntu:~/n/node-ws$ sudo nodejs index.js
connection

events.js:74
    throw TypeError('Uncaught, unspecified "error" event.');
          ^
TypeError: Uncaught, unspecified "error" event.
    at TypeError (<anonymous>)
    at WebSocket.EventEmitter.emit (events.js:74:15)
    at Receiver.self._receiver.onerror (/home/s0beit/n/node-ws/node_modules/ws/lib/WebSocket.js:704:10)
    at Receiver.error (/home/s0beit/n/node-ws/node_modules/ws/lib/Receiver.js:295:8)
    at Receiver.processPacket (/home/s0beit/n/node-ws/node_modules/ws/lib/Receiver.js:192:12)
    at Receiver.add (/home/s0beit/n/node-ws/node_modules/ws/lib/Receiver.js:87:24)
    at firstHandler (/home/s0beit/n/node-ws/node_modules/ws/lib/WebSocket.js:658:22)
    at process._tickCallback (node.js:415:13)

I'm getting this with a custom client I was writing

char handshake[2048];

sprintf(handshake, 
    "GET %s HTTP/1.1\r\n"
    "Host: %s\r\n"
    "Upgrade: websocket\r\n"
    "Origin: http://%s:%u%s\r\n"
    "Connection: Upgrade\r\n"
    "Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n"
    "Sec-WebSocket-Protocol: chat\r\n"
    "Sec-WebSocket-Version: 13\r\n\r\n",
    path, host, host, port, path);

printf("=== Sending Handshake ===\n");
printf("%s", handshake);

if(send(fd, handshake, sizeof(handshake), 0) == -1) {
    error("send handshake");
}

// Wait for reply...
char recvBuffer[1024];

memset(recvBuffer, 0, sizeof(recvBuffer));

if(recv(fd, recvBuffer, sizeof(recvBuffer), 0) == -1) {
    error("handshake reply");
}

printf("=== Got Reply ===\n");
printf("%s", recvBuffer);

I get a reply from the server, then I close the connection. This error occurs before the connection is closed, after the reply.

s0beit@ubuntu:~/n/websocket$ ./websocket1 localhost 8080 /
Connecting: ws://localhost:8080/
=== Sending Handshake ===
GET / HTTP/1.1
Host: localhost
Upgrade: websocket
Origin: http://localhost:8080/
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat
Sec-WebSocket-Version: 13

=== Got Reply ===
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

s0beit@ubuntu:~/n/websocket$ 

@varmando
Copy link

varmando commented Jan 3, 2015

My quick'n'dirty hack. Use at your own risk.

--- ws/lib/WebSocket.js 2015-01-03 12:38:40.666944302 +0200
+++ ws-patched/lib/WebSocket.js 2015-01-03 12:40:48.570946126 +0200
@@ -824,7 +824,7 @@
   self._receiver.onerror = function onerror(reason, errorCode) {
     // close the connection when the receiver reports a HyBi error code
     self.close(typeof errorCode !== 'undefined' ? errorCode : 1002, '');
-    self.emit('error', reason, errorCode);
+    //self.emit('error', reason, errorCode);
   };

   // finalize the client

@matghaleb
Copy link

@Dragonight Thx very much for your hack 👍 it's working fine for me.
Hope a fix will be provided soon..

@guillaumepotier
Copy link

@Dragonight @matghaleb 👍

@boynet
Copy link

boynet commented Jun 29, 2015

thanks, any reason its not got fixed?

@klinquist
Copy link

My API using ws started crashing every day or so, I put in a listener, and see that it's this error ("reserved fields must be empty 1002"). I am connecting to it with IPWorks ws client and we're only sending basic json strings, any ideas?

@rainder
Copy link

rainder commented Nov 13, 2015

I get "Uncaught, unspecified "error" event. (reserved fields must be empty)" when I write raw json object to the socket after connection has established

  let socket = net.connect({
    port: 2001,
    host: '127.0.0.1'
  }, function () {
    console.log('connected');
    socket.write([
      'GET / HTTP/1.1',
      'Host: localhost',
      'Upgrade: websocket',
      'Origin: partner',
      'Connection: Upgrade',
      'Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==',
      'Sec-WebSocket-Protocol: splyt-protocol',
      'Sec-WebSocket-Version: 13',
      '', ''
    ].join('\n'));

    setTimeout(function () {
      socket.write(JSON.stringify({}));
    }, 200);
  });

that fixes the problem.

webSocketServer.on('connection', function (socket) {
  socket.on('error', function (err) {
    //handle or ignore the error
  });
});

@lpinca
Copy link
Member

lpinca commented Oct 18, 2016

Handling the error event that is emitted on the WebSocket instance should fix this.
Please comment back if you still have issues.

@lpinca lpinca closed this as completed Oct 18, 2016
@fahmi4bd
Copy link

fahmi4bd commented Sep 29, 2017

problem_closeandopenitself

Hi everybody, i need know why the ws client close and open it self in server. And this happend to all client.

and the script in bottom

sequoiar pushed a commit to InstantWebP2P/wspp that referenced this issue Apr 25, 2020
Fixed issue websockets/ws#246.

The occurred error with reason "invalid error code" crashes program execution. This patch helps to fix this problem.
@tbanj
Copy link

tbanj commented May 30, 2021

@rainder, thanks your fix works for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests