Skip to content

fix(extension): suppress ERR_CONNECTION_REFUSED and harden WebSocket lifecycle#97

Open
huangsen365 wants to merge 1 commit intojackwener:mainfrom
huangsen365:fix/extension-ws-connection-refused
Open

fix(extension): suppress ERR_CONNECTION_REFUSED and harden WebSocket lifecycle#97
huangsen365 wants to merge 1 commit intojackwener:mainfrom
huangsen365:fix/extension-ws-connection-refused

Conversation

@huangsen365
Copy link

Problem

When the opencli daemon is not running, the Chrome extension's WebSocket reconnect loop produces noisy ERR_CONNECTION_REFUSED console errors every few seconds:

WebSocket connection to 'ws://localhost:19825/ext' failed: 
Error in connection establishment: net::ERR_CONNECTION_REFUSED

These errors:

  • Cannot be caught via try/catch (Chrome logs them before JS gets control)
  • Clutter the Service Worker console
  • May confuse users into thinking something is broken

Additionally, several race conditions existed in the WebSocket lifecycle.

Solution

Probe before connect: Use fetch(HEAD) to check if the daemon is reachable before opening a WebSocket. A failed fetch is silent — no console noise. Only proceed with WebSocket when daemon is confirmed up.

Harden lifecycle:

  • Add connecting guard flag to prevent concurrent connect() calls from overlapping alarm/event triggers
  • Check WebSocket.CLOSING state to avoid creating a new socket while the old one is still shutting down
  • Capture socket in local variable to prevent stale reference races between onclose/onerror callbacks
  • Wrap socket.close() in try/catch in onerror (can throw during SW teardown)
  • Only send command responses if the socket is still the active one and OPEN

Testing

  • Daemon stopped → extension quietly retries with exponential backoff, no console errors
  • Daemon started → extension connects within one backoff cycle
  • Daemon restarted → extension reconnects cleanly after onclose fires

…ocket lifecycle

Problems:
- When the opencli daemon is not running, the extension's WebSocket
  reconnect loop produces noisy ERR_CONNECTION_REFUSED console errors
  that cannot be caught or suppressed via try/catch (Chrome limitation).
- WebSocket constructor could throw during Service Worker teardown.
- Race conditions between connect() calls from multiple alarm/event
  triggers could create duplicate sockets.
- ws.close() in onerror handler could throw if SW context is gone.

Fixes:
- Probe daemon reachability via fetch(HEAD) before opening WebSocket.
  A failed fetch is silent; only connect WebSocket when daemon is up.
- Add 'connecting' guard flag to prevent concurrent connect() calls.
- Check WebSocket CLOSING state to avoid creating new socket while
  old one is still shutting down.
- Capture socket in local variable to avoid stale reference races.
- Wrap socket.close() in try/catch in onerror handler.
- Only send responses if the socket is still the active one and OPEN.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant