-
-
Notifications
You must be signed in to change notification settings - Fork 697
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Bug Description
When calling close() on a CONNECTING WebSocket, the readyState property is 3 (CLOSED) during the close event handler, but incorrectly reverts to 2 (CLOSING) after the handler returns. Once a WebSocket reaches the CLOSED state, it should never transition back to CLOSING.
Reproducible By
const { WebSocket } = require('undici');
const ws = new WebSocket('wss://echo.websocket.events/');
let capturedReadyState;
ws.addEventListener('close', () => {
capturedReadyState = ws.readyState;
console.log('during close event, readyState =', ws.readyState);
});
ws.close();
console.log('after close(), readyState =', ws.readyState);
setTimeout(() => {
console.log('captured readyState from inside handler =', capturedReadyState);
console.log('after 10ms, readyState =', ws.readyState);
}, 10);
setTimeout(() => {
console.log('after 100ms, readyState =', ws.readyState);
// Expected: readyState should be 3 (CLOSED) after close event
// Bug: readyState is 2 (CLOSING) after the event handler returns
if (ws.readyState === 3) {
console.log('PASS: readyState is CLOSED (3)');
} else {
console.log('FAIL: readyState is', ws.readyState, '(expected 3)');
}
process.exit(0);
}, 100);
setTimeout(() => {
console.log('Timeout - something went wrong');
process.exit(1);
}, 5000);Expected Behavior
after close(), readyState = 2
captured readyState from inside handler = undefined
after 10ms, readyState = 2
during close event, readyState = 3
after 100ms, readyState = 3
PASS: readyState is CLOSED (3)
See: https://jsbin.com/vugosuzeqa/edit?html,js,output
This follows from how the spec synchronously changes the state to CLOSING in https://websockets.spec.whatwg.org/#dom-websocket-close , and then after closing, queues a task to change the state to CLOSED and fire events.
So, this is probably the same root cause as #4741.
Relevant WPTs:
- https://github.com/web-platform-tests/wpt/blob/master/websockets/interfaces/WebSocket/close/close-connecting.html
- https://github.com/web-platform-tests/wpt/blob/master/websockets/interfaces/WebSocket/close/close-connecting-async.any.js
Logs & Screenshots
Actual behavior:
during close event, readyState = 3
after close(), readyState = 2
captured readyState from inside handler = 3
after 10ms, readyState = 2
after 100ms, readyState = 2
FAIL: readyState is 2 (expected 3)
The misordering is again related to #4741.
Environment
- Node v25.2.1
- undici 7.18.2
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working