Node.js native WebSocket doesn't fire onclose after onerror — reconnect never triggers
Problem
When using Node.js 22+ native WebSocket (globalThis.WebSocket) to connect to a server that isn't ready yet or drops the connection, the onerror event fires but onclose does not follow. If reconnection logic is only in onclose, the client silently dies after the first failed connection attempt and never reconnects.
Symptoms
- WebSocket silently stops reconnecting
- no onclose fired after onerror
- WebSocket connects once and never retries
Stack
Solution
Trigger reconnect from both onerror and onclose, using a flag to prevent duplicate reconnect scheduling: 1. Add a `reconnected` boolean flag scoped to each connection attempt 2. Create a `scheduleReconnect()` helper that checks the flag before scheduling 3. Call `scheduleReconnect()` from both `onerror` and `onclose`
Code
function connectWs() {
const ws = new globalThis.WebSocket(url);
let reconnected = false;
const scheduleReconnect = () => {
if (reconnected) return;
reconnected = true;
setTimeout(connectWs, 5000);
};
ws.onopen = () => console.log("WebSocket connected");
ws.onclose = () => scheduleReconnect();
ws.onerror = (err) => {
console.error("WebSocket error:", err);
scheduleReconnect();
};
}Caveats
This applies to Node.js native WebSocket (globalThis.WebSocket). Browser WebSocket and libraries like 'ws' typically do fire onclose after onerror. Also consider adding a periodic settings refresh via HTTP API as a secondary fallback.