diff --git a/lib/web/websocket/connection.js b/lib/web/websocket/connection.js index 4ecc8a195fc..e9f2c62ebb5 100644 --- a/lib/web/websocket/connection.js +++ b/lib/web/websocket/connection.js @@ -316,7 +316,7 @@ function failWebsocketConnection (handler, code, reason, cause) { if (isConnecting(handler.readyState)) { // If the connection was not established, we must still emit an 'error' and 'close' events - handler.onSocketClose() + handler.onSocketClose(cause) } else if (handler.socket?.destroyed === false) { handler.socket.destroy() } diff --git a/lib/web/websocket/websocket.js b/lib/web/websocket/websocket.js index da94ab5b352..9ce88874955 100644 --- a/lib/web/websocket/websocket.js +++ b/lib/web/websocket/websocket.js @@ -92,7 +92,7 @@ class WebSocket extends EventTarget { this.#handler.socket.destroy() }, - onSocketClose: () => this.#onSocketClose(), + onSocketClose: (cause) => this.#onSocketClose(cause), onPing: (body) => { if (channels.ping.hasSubscribers) { channels.ping.publish({ @@ -565,7 +565,7 @@ class WebSocket extends EventTarget { * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol * @see https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.4 */ - #onSocketClose () { + #onSocketClose (cause) { // If the TCP connection was closed after the // WebSocket closing handshake was completed, the WebSocket connection // is said to have been closed _cleanly_. @@ -599,7 +599,7 @@ class WebSocket extends EventTarget { code = 1006 fireEvent('error', this, (type, init) => new ErrorEvent(type, init), { - error: new TypeError(reason) + error: new TypeError(reason, cause ? { cause } : undefined) }) } diff --git a/test/websocket/issue-4273.js b/test/websocket/issue-4273.js index d41e35665c3..b82860f48b1 100644 --- a/test/websocket/issue-4273.js +++ b/test/websocket/issue-4273.js @@ -5,12 +5,14 @@ const { WebSocket } = require('../..') const { once } = require('node:events') test('first error than close event is fired on failed connection', async (t) => { - t.plan(1) + t.plan(3) - const ws = new WebSocket('ws://localhost:1') + const ws = new WebSocket('ws://localhost:999') ws.addEventListener('error', (ev) => { t.assert.ok(ev.error instanceof TypeError) + t.assert.ok(ev.error.cause, 'error should have a cause') + t.assert.strictEqual(ev.error.cause.code, 'ECONNREFUSED', 'error should have a cause code of ECONNREFUSED') }) await once(ws, 'close')