From 9957205ab4800478ee2ea8443830271d51b6b9e7 Mon Sep 17 00:00:00 2001 From: M-YasirGhaffar Date: Fri, 6 Feb 2026 01:27:35 +0500 Subject: [PATCH] websocket: provide descriptive error on abnormal closure (fixes #4625) Signed-off-by: M-YasirGhaffar --- lib/web/websocket/websocket.js | 2 +- test/websocket/issue-4625.js | 46 ++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 test/websocket/issue-4625.js 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() +})