Closed d4rkstar closed 6 years ago
See #1201, is there a way to reproduce the issue?
Are you by any chance throwing an error from the 'error'
listener and using process.once('uncaughtException')
?
This is the only way I can make http.ClientRequest
emit the 'error'
event twice on Node.js 8:
const http = require('http');
const host = 'a'.repeat(10);
let req = http.get({ host });
req.on('error', (err) => {
if (req.aborted) return;
req = null;
throw err;
});
process.once('uncaughtException', () => {});
Can you also please add more details?
Thanks.
Hello Luigi, thank you for your feedback. Fortunately i've logs about the error :)
Before, i'll give you more informations about my environment:
Using webstomp over websocket with SSL:
let stomp_url = 'wss://remotehost:8443/ws';
self.client = webstomp.over(new WebSocket(stomp_url), options);
The trace:
2017-10-24T09:33:14.779Z ERROR uncaughtException: connect ECONNREFUSED xxx.xxx.xxx.xxx:8443
{"date":"Tue Oct 24 2017 11:33:14 GMT+0200 (CEST)","process":{"pid":23454,"uid":1001,"gid":1001,"cwd":"/home/myapp/myapp","execPath":"/usr/bin/node","version":"v8.6.0","argv":["/usr/bin/node","/home/myapp/myapp/www"],"memoryUsage":{"rss":91394048,"heapTotal":51220480,"heapUsed":38065344,"external":239175}},"os":{"loadavg":[0,0,0],"uptime":1794013},"trace":[{"column":11,"file":"util.js","function":"Object._errnoException","line":1019,"method":"_errnoException","native":false},{"column":20,"file":"util.js","function":"_exceptionWithHostPort","line":1041,"method":null,"native":false},{"column":14,"file":"net.js","function":"TCPConnectWrap.afterConnect [as oncomplete]","line":1175,"method":"afterConnect [as oncomplete]","native":false}],"stack":["Error: connect ECONNREFUSED xxx.xxx.xxx.xxx:8443"," at Object._errnoException (util.js:1019:11)"," at _exceptionWithHostPort (util.js:1041:20)"," at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1175:14)"]}
Regards
Thanks, that seems a different error though (not the one in the issue title) and it isn't caught because you didn't add an 'error'
listener to the WebSocket
instance.
Ok, I can reproduce with this code:
const WebSocket = require('ws');
const ws = new WebSocket('wss://localhost');
process.on('uncaughtException', (err) => {
console.error(err);
});
$ node index.js
{ Error: connect ECONNREFUSED 127.0.0.1:443
at Object._errnoException (util.js:1021:11)
at _exceptionWithHostPort (util.js:1043:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1175:14)
code: 'ECONNREFUSED',
errno: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 443 }
TypeError: Cannot read property 'aborted' of null
at ClientRequest._req.on (/home/luigi/1229/node_modules/ws/lib/WebSocket.js:646:19)
at emitOne (events.js:115:13)
at ClientRequest.emit (events.js:210:7)
at TLSSocket.socketCloseListener (_http_client.js:361:9)
at emitOne (events.js:120:20)
at TLSSocket.emit (events.js:210:7)
at _handle.close (net.js:547:12)
at TCP.done [as _onclose] (_tls_wrap.js:356:7)
but this is not an issue in ws
.
The problem here is the use of 'uncaughtException'
. We are emitting an 'error'
event here and if there are no listeners the error is thrown. The 'uncaughtException'
listener prevents the process from exiting. The thrown error prevents this flag from being set and for this reason a second 'error'
event is emitted.
This no longer happens in Node.js 9 (https://github.com/nodejs/node/commit/620ba41694) but there is nothing wrong also in previous versions of Node.js. 'uncaughtException'
should not be used.
Thank you again Luigi. Will change my code and will update or close this issue
Any update here?
Closing due to inactivity. If your issue is still unresolved, please comment back and I will reopen this.
Having the same problem here when using ws
in Electron.
same here with electron!
Having the problem since I switched to the very first version in which you support handshakeTimeout (something around 3.0.2 or so)
From this version on up to the latest: If this sequence goes into "error", I'll receive an exception
TypeError: Cannot read property 'setHeader' of null
a couple of seconds after the error occurs. The first attempt fails as expected after 5s
Error: Opening handshake has timed out
If I repeat the sequence then, it immediately fails with
Error: connect EHOSTDOWN 192.168.188.98:8888 - Local (192.168.188.24:57769)
but then after 5 s the exception occurs. For me it looks like as if you would not terminate the handshakeTimer on error
let server = new ws(argv.ws_uri, {handshakeTimeout: 5000})
server.on('open', () => {
server.send(JSON.stringify({
id: 1,
method: "ping",
params: {
interval: 3000
},
jsonrpc: "2.0"
}))
})
server.on('message', (data) => {
console.log(data)
res.send("OK")
})
server.on('error', (error) => {
console.log(error)
res.send("ERROR "+error)
})
@accuware your issue is different from the one reported by the original poster. In your case it seems that
https://github.com/websockets/ws/blob/14d9088391ac4495d04e64d76c3b83d4e75f80e2/lib/websocket.js#L542
is called after the 'error'
or the 'upgrade'
event is emitted on the req
object which would be a bug in Node.js. Are you able to create a reproducible test case?
https://github.com/websockets/ws/blob/d0741faeec6fc6bc6db163545b3534ed822f6cf3/lib/WebSocket.js#L639
It seems that, if a previous error occurs, this._req is null. So this line seems to produce an exception.