Bug Description
After a WebSocket connection is established, the error event is not dispatched on network failures; only the close event is emitted.
Reproducible By
const { WebSocketServer } = require('ws')
const { setGlobalDispatcher, Agent, WebSocket } = require('undici')
let socket
// extract the underlying socket, so we can destroy it later
setGlobalDispatcher(new (class foo extends Agent {
dispatch(opts, handler) {
return super.dispatch(opts, {
...handler,
onUpgrade(statusCode, headers, _socket) {
socket = _socket
return handler.onUpgrade(statusCode, headers, _socket)
}
})
}
})())
const server = new WebSocketServer({ port: 0 })
const ws = new WebSocket(`ws://localhost:${server.address().port}`)
ws.onopen = () => {
console.log('open')
setTimeout(() => {
console.log('destroying socket')
socket.destroy(new Error('foo'))
}, 1000)
}
ws.onerror = () => console.log('error')
ws.onclose = e => console.log('close', e.code)
Expected Behavior
According to WHATWG WebSockets Standard section 4. Feedback from the protocol:
When the WebSocket connection is closed, possibly cleanly, the user agent must queue a task to run the following substeps:
- Change the ready state to CLOSED (3).
- If the user agent was required to fail the WebSocket connection, or if the WebSocket connection was closed after being flagged as full, fire an event named error at the WebSocket object. [WSP]
- Fire an event named close at the WebSocket object, [...]
Note the 2. If the user agent was required to fail the WebSocket connection, [...], fire an event named error.
According to RFC 6455 section 7.1.7. Client-Initiated Closure:
If at any point the underlying transport layer connection is unexpectedly lost, the client MUST _Fail the WebSocket Connection_.
A net.Socket is destroyed with an ErrnoException when the network connection is lost. Therefore, the WebSocket client should fail the connection and dispatch an error event.
Logs & Screenshots
Running the reproduction:
$ node index.js
open
destroying socket
close 1006
^ Notice that no error message is logged.
I tried this in Firefox: connected to the remote WebSocket and then brought the network interface down. In that case, the error listener was called after the connection was lost.

Bug Description
After a WebSocket connection is established, the
errorevent is not dispatched on network failures; only thecloseevent is emitted.Reproducible By
Expected Behavior
According to WHATWG WebSockets Standard section 4. Feedback from the protocol:
Note the
2. If the user agent was required to fail the WebSocket connection, [...], fire an event named error.According to RFC 6455 section 7.1.7. Client-Initiated Closure:
A
net.Socketis destroyed with anErrnoExceptionwhen the network connection is lost. Therefore, the WebSocket client should fail the connection and dispatch anerrorevent.Logs & Screenshots
Running the reproduction:
^ Notice that no
errormessage is logged.I tried this in Firefox: connected to the remote WebSocket and then brought the network interface down. In that case, the
errorlistener was called after the connection was lost.