ws: read ECONNRESET error on disconnect (ws 3.3.3)
- I’ve searched for any related issues and avoided creating a duplicate issue.
Description
Upon updating to ws 3.3.3, when a client disconnects the following exception is thrown:
events.js:183
throw er; // Unhandled 'error' event
^
Error: read ECONNRESET
at _errnoException (util.js:1024:11)
at TCP.onread (net.js:615:25)
Code works fine in previous version.
Reproducible in:
version: 3.3.3 Node.js version(s): v8.9.1 OS version(s): Windows 10 Pro, Fall update
Steps to reproduce:
- Create a websocket server
- Connect to the websocket server via Chrome (`new WebSocket(‘ws://localhost:3000’))
- Disconnect from the websocket server (via refreshing the page in Chrome)
Expected result:
The disconnect is handled gracefully, with the ‘close’ event being called.
Actual result:
An exception is thrown, which crashes the app:
events.js:183
throw er; // Unhandled 'error' event
^
Error: read ECONNRESET
at _errnoException (util.js:1024:11)
at TCP.onread (net.js:615:25)
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 68
- Comments: 51 (18 by maintainers)
Commits related to this issue
- Ignore ECONNRESET on connection close ws@3.3.3 stopped swalling ECONNRESET inside the library upon a connection close event. This commit swallows it when we know we are attempting to disconnect. Rel... — committed to chadxz/awry by chadxz 7 years ago
- fixing crash due to chrome https://github.com/websockets/ws/issues/1256 — committed to o3LL/VeryNiceBoard by deleted user 6 years ago
- Fix for ws issue: https://github.com/websockets/ws/issues/1256. Improve client behavior and update when new data arrives. — committed to vega/falcon by domoritz 6 years ago
- Handle crashing error when client disconnects An listener for the 'error' event is now required in ws to avoid disconnecting clients in some browsers (especially Chrome) from cause a crash. See this ... — committed to cwkummer/chat-app-react-redux-saga-websockets by cwkummer 6 years ago
- Reason: Chrome 63+ does closes socket without waiting for close frame from server. Upstream WS library then throws on server. Puppeteer was upgraded to handle this in the following commits - https://... — committed to eriktrom/url-to-pdf-api by eriktrom 6 years ago
- Upgrade puppeteer and ws libraries fixes #57 Reason: Chrome 63+ does closes socket without waiting for close frame from server. Upstream WS library then throws on server. Puppeteer was upgraded to h... — committed to eriktrom/url-to-pdf-api by eriktrom 6 years ago
- Upgrade puppeteer and ws libraries fixes #57 Reason: Chrome 63+ does closes socket without waiting for close frame from server. Upstream WS library then throws on server. Puppeteer was upgraded to h... — committed to eriktrom/url-to-pdf-api by eriktrom 6 years ago
- Upgrade puppeteer and ws libraries fixes #57 Reason: Chrome 63+ does closes socket without waiting for close frame from server. Upstream WS library then throws on server. Puppeteer was upgraded to h... — committed to RepairShopr/url-to-pdf-api by eriktrom 6 years ago
- Try to handle ws ECONNRESET error https://github.com/websockets/ws/issues/1256 — committed to JasonSteck/WS-Nexus by deleted user 6 years ago
- Modifies the LRWebSocketServer prototype - Listens for error events on the websocket instance to avoid uncaught ECONNRESET exceptions. When no listener is attached to error event from the websocket ... — committed to Driptap/easy-livereload by sinan-guclu-pupil 6 years ago
- Catch and log errors in BigDigServer Summary: There is a scary comment in `BigDigServer` about not handling WS/HTTPS server errors, and I think I managed to encounter one. I'm not sure how to reprodu... — committed to facebookarchive/nuclide by hansonw 6 years ago
- Fixed server crash when client disconnects More info: https://github.com/websockets/ws/issues/1256 — committed to McXinuS/Synthusic by McXinuS 6 years ago
- fix: catch websocket error events WebSockets can throw an error event that has to be captured in node to prevent application crashing. This seems to be crashing WebKit Linux on some of the bots with... — committed to aslushnikov/playwright by aslushnikov 4 years ago
Issue is caused by lack of error listener on the socket, and can be fixed like so:
This isn’t documented in the README.md, and seems to be a pretty big breaking change.
@lpinca You document that that event is where any errors from underlying
net.Socketare forwarded to, but not the fact that a simple client disconnection will cause such an exception.To me, because you have a
'close'event, I’d assume that exceptions caused as a result of a client disconnecting would be handled by this library, since it’s something that the library seems to be able to detect and act on.I think is a reasonable assumption to make, given that clients disconnecting is a perfectly normal event for a socket server.
I’m in the same boat.
this doesn’t solve the problem.
I can confirm this statement, when the handler is applied to the server. No more crashes when applied to each connection individually.
These errors occur quite often on Chrome V 63.0.3239.84 (=latest for my distribution).
FF 57.0.3 doesn’t produce this error at all. Same with Edge on Windows clients.
Node v8.9.3 ws 3.3.3 ubuntu1~16.04.5 Linux 4.4.0-21-generic (x86_64)
According to https://bugs.chromium.org/p/chromium/issues/detail?id=798194#c6 this works as intended.
What we can do here is adding a default
'error'listener which is a noop, so people are not forced to add one. Users can still get errors by adding their own'error'listener(s).Thoughts?
@endel the error is not a bug in the library and https://github.com/websockets/ws/issues/1256#issuecomment-354305677 is the proof. The fact that it only happens on Chrome is another proof.
You get the error only on
ws@>=3.3.3because it is the first version that does not swallow thenet.Socketerrors.Another possible workaround for Chrome is calling
close()from a listener of the'beforeunload'event:Everyone please add a listener for the
'error'event on theWebSocketinstance.Nevermind, here is a test case which doesn’t use
ws:This still happens on 4.0.0, adding both
errorandcloseevent handlers onwsinstance doesn’t help.@ProgrammingLife it should. In https://github.com/websockets/ws/issues/1266#issue-285162876 you added the listener on the server so make sure you are adding it to the
WebSocketinstance instead.@G-Rath
Yes because it shouldn’t, the issue seems to happen only on Chrome 63.
Swallowing errors is never a good idea. Developers can ignore errors but they may want to know if the connection was closed cleanly or not.
@quigleyj97
I didn’t check but maybe latest Chrome sends the close frame and abruptly closes the connection immediately after that.
Closing as we are no longer re-emitting
net.Socketerrors on version 5.I didn’t expect to create so much disruption by re-emitting
net.Socketerrors as I assumed that everyone already had'error'listeners set up but I was wrong and it seems that these errors are ignored anyway, so I’m thinking to not re-emit them again, restoring behavior ofws@<=3.3.2.What do you think? It would be great if you could test upcoming changes installing from GitHub.
Thanks.
No, there are no side effects, the
WebSocketis always closed when an error occurs, so you can use a noop as listener if you don’t care about errors.idk then. works fine for me.
my code(server):
const WebSocket = require(‘ws’);
const wss = new WebSocket.Server({ port: 8080 });
wss.on(‘connection’, function(ws) { ws.on(‘message’, function(message) { console.log("msg: " + message); });
ws.on(‘close’, function(){ console.log(“client closed connection!”); });
ws.on(‘error’, function(e){ console.log("error!: " + e); })
ws.send(‘something’); });
just add onerror and onclose (inside of wss.on.(‘connection’,…)) to your server :
ws.on(‘close’, function(){ console.log(“client closed connection!”); });
ws.on(‘error’, function(e){ console.log("error!: " + e); })
Apologies for commenting on an old issue, but this is still a problem.
Whenever a client disconnects while a large amount of data is being sent, I consistently get full server crashes. Everywhere in my code, I’ve added listeners to the
errorevent where possible; on the http server, request and response object, the socket server and each individual client. I’ve even gone as far asws._socket.on('error', () => ...), but to no avail.Using ws 7.4.2, running on Node v14.15.4 on Ubuntu 20.04.
I’m actually unsure if this is a node internal error or has something to do with this library, since I also get ECONNRESET errors that I can’t seem to catch from time to time.
edit:
Right as I finished up writing this post, I figured the listener was attached too late to the
errorevent. My server runs inside a worker thread and the issue only seems to occur when my CPU load is reasonably high. The crash happened when the HTTP-serverconnectionevent is fired, then the client disconnects, and then therequestshould be fired. It’s not a problem with this library, but the fact theerrorevent is emitted from the socket before an event listener is attached to it.For anyone running into similar issues: The fix for me was to attach a listener to the
errorevent immediately as the client connects, and not a ‘tick’ later, because the client disconnects after theconnectionevent, but before theupgradeevent.So, instead of:
All you have to do is bind the listener during the
connectionevent.Haha, negative. I was using ws for a project of mine, so was figuring stuff out when I ran across the issue. All good now though!
First, thanks for the great library. I am testing it out on a really cool IoT prototype. I love that it does one thing good. I ran into this error the last couple days. I am guessing because my headless client timed out it’s http connection for whatever reason (don’t have ping pong going yet, just a reconnect on the heartbeat.)
Anyways, I had already set up the error handler in connection event for the connected socket. So I was a little surprised that the server halted on this error. I realize that the error is not going to be re-emitted, but I guess I am confused by that. Why wouldn’t that error get handled the way it was intended?
@Hypnosphi only if you are using
onerroras per https://github.com/websockets/ws/commit/63e275e75f8ab8f4385e7ef104a74c582cd0c793.Looks like you’re right.
According to your message it seems like error is happening on connected client instance, not whole server. That
wsandwsswasn’t distinguishable enough in the example. That’s why I am always usingclientas name insideconnection.So to resolve the issue we should use:
This is perfectly fine, I’ll always vote for explicit code - this just needs to be explained in README.
Spent some time figuring this one out in my unit tests. I had code like this to finish the tests:
The problem is that the server tries to close before the event from the client reaches it, hence forcing the close connection and causing the error.
So I’m doing this now:
I don’t know how you are using it but if the client and server are two separate processes then ofc the server does not crash because of the client. From I what I can see puppeteer uses ws only as client.
Socket.IO seems to correctly add the
'error'listener on both the server and client. Same is for puppeteer. I’ve only checked the latest versions though.The read
ECONNRESETerror can be emitted also on the client not only the server.@jkasun well all browsers sends a close frame when you refresh the page if you didn’t already close the WebSocket. The problem is that Chrome closes the TCP socket while the server response is on the wire.
To be honest I don’t know why it doesn’t do the same when the WebSocket is closed from a listener of the
'beforeunload'event. Maybe it does but the small timing difference is sufficient (at least for the above example) to prevent the issue from happening.