diff --git a/lib/web/websocket/websocket.js b/lib/web/websocket/websocket.js index 331497677a3..3138a030f3d 100644 --- a/lib/web/websocket/websocket.js +++ b/lib/web/websocket/websocket.js @@ -587,7 +587,7 @@ class WebSocket extends EventTarget { code = 1006 fireEvent('error', this, (type, init) => new ErrorEvent(type, init), { - error: new TypeError(reason) + error: new TypeError(reason || 'WebSocket connection closed abnormally') }) } diff --git a/test/websocket/issue-4625.js b/test/websocket/issue-4625.js new file mode 100644 index 00000000000..5c6a5288fde --- /dev/null +++ b/test/websocket/issue-4625.js @@ -0,0 +1,46 @@ +'use strict' + +const { test } = require('node:test') +const net = require('node:net') +const { WebSocket } = require('../..') + +// Test for https://github.com/nodejs/undici/issues/4625 +// When WebSocket closes abnormally (code 1006), error message should be descriptive +test('abnormal closure should have descriptive error message', async (t) => { + // Create a raw TCP server that accepts the connection but then abruptly closes + const server = net.createServer((socket) => { + // Send a valid WebSocket handshake response + socket.write( + 'HTTP/1.1 101 Switching Protocols\r\n' + + 'Upgrade: websocket\r\n' + + 'Connection: Upgrade\r\n' + + 'Sec-WebSocket-Accept: invalid\r\n' + + '\r\n' + ) + // Immediately destroy the socket to simulate abnormal closure + socket.destroy() + }) + + await new Promise((resolve) => server.listen(0, resolve)) + const port = server.address().port + + const ws = new WebSocket(`ws://localhost:${port}`) + + await new Promise((resolve) => { + ws.addEventListener('error', (event) => { + t.assert.ok(event.error instanceof TypeError) + t.assert.ok( + event.error.message.length > 0, + 'error message should not be empty' + ) + t.assert.ok( + event.error.message.includes('abnormally') || + event.error.message.includes('closed'), + 'error message should describe the closure' + ) + resolve() + }) + }) + + server.close() +})