Change Socket.IO connection error logging from error to log level (#448)

* fix: stop reporting transient WebSocket connect_error to Sentry

connect_error fires on every retry attempt (e.g. iOS Safari dropping
WebSocket during network transitions). Using logger.error routed each
attempt to Sentry.captureException, generating noise for a self-healing
failure. Switch to logger.log (no-op in production); the real failure
path (reconnect_failed) still uses logger.error and surfaces in Sentry.

https://claude.ai/code/session_01TpZ9W111Trkv2g4CkCWFpB

* refactor(useDraftSocket): clean up reconnect event handling

- Remove redundant reconnect_attempt listener: connect_error already
  sets isReconnecting(true), and connectionError is never set before
  reconnect_attempt fires, making that handler a no-op
- Wrap reconnect_failed in an Error object so Sentry receives a proper
  exception with stack trace instead of a plain captureMessage string
- Store handleReconnectFailed as a named reference so socket.io.off()
  removes only this listener rather than all reconnect_failed listeners

https://claude.ai/code/session_01TpZ9W111Trkv2g4CkCWFpB

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Chris Parsons 2026-05-19 15:47:41 -07:00 committed by GitHub
parent 43dbdf0040
commit 06d415d95c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -64,7 +64,7 @@ export function useDraftSocket(seasonId: string, teamId?: string): UseDraftSocke
});
socket.on("connect_error", (error) => {
logger.error("Socket.IO connection error:", error);
logger.log("Socket.IO connection error:", error);
// Don't set connectionError here — reconnect_attempt fires immediately after
// and would clear it again, causing the error overlay to flicker on every
// retry. Only show a hard error once all attempts are exhausted (reconnect_failed).
@ -72,17 +72,13 @@ export function useDraftSocket(seasonId: string, teamId?: string): UseDraftSocke
setIsReconnecting(true);
});
socket.io.on("reconnect_attempt", () => {
logger.log("Attempting to reconnect...");
setIsReconnecting(true);
setConnectionError(null);
});
socket.io.on("reconnect_failed", () => {
logger.error("Reconnection failed");
const handleReconnectFailed = () => {
logger.error(new Error("Socket.IO reconnection failed after max attempts"));
setConnectionError("Failed to reconnect. Please refresh the page.");
setIsReconnecting(false);
});
};
socket.io.on("reconnect_failed", handleReconnectFailed);
const handleOffline = () => {
// Mark as reconnecting immediately — the OS fires this before Socket.IO's
@ -119,8 +115,7 @@ export function useDraftSocket(seasonId: string, teamId?: string): UseDraftSocke
document.addEventListener("visibilitychange", handleVisibilityChange);
return () => {
socket.io.off("reconnect_attempt");
socket.io.off("reconnect_failed");
socket.io.off("reconnect_failed", handleReconnectFailed);
window.removeEventListener("offline", handleOffline);
window.removeEventListener("online", handleReturn);
document.removeEventListener("visibilitychange", handleVisibilityChange);