chenhg5/cc-connect · error
read: %w
Error message
read: %w
What it means
In the steady-state message loop, conn.ReadMessage failed while reading the next WebSocket frame; the error is wrapped as 'read: %w'. This terminates runConnection for this attempt and connectLoop reconnects. Any successfully-read but malformed JSON frames are only logged and skipped — this error is specifically a transport-level read failure.
Source
Thrown at platform/wecom/websocket.go:271
slog.Info("wecom-ws: subscribed successfully", "bot_id", p.botID)
p.missedPong.Store(0)
// Start heartbeat goroutine
heartCtx, heartCancel := context.WithCancel(p.ctx)
defer heartCancel()
go p.heartbeat(heartCtx, conn)
// Read loop
for {
select {
case <-p.ctx.Done():
return p.ctx.Err()
default:
}
_, raw, err := conn.ReadMessage()
if err != nil {
return fmt.Errorf("read: %w", err)
}
var frame wsFrame
if err := json.Unmarshal(raw, &frame); err != nil {
slog.Warn("wecom-ws: invalid json", "error", err)
continue
}
p.handleFrame(frame)
}
}
// handleFrame dispatches incoming frames by cmd or req_id prefix.
func (p *WSPlatform) handleFrame(frame wsFrame) {
switch frame.Cmd {
case "aibot_msg_callback":
p.handleMsgCallback(frame)
case "aibot_event_callback":View on GitHub (pinned to 4000b2338a)
Solutions
- Confirm heartbeat/pong keepalive is functioning (missedPong resets) — frequent reads errors on idle links indicate keepalive issues.
- Check the wrapped cause: 'close 1006' = abnormal close (network); clean close codes point to server-initiated disconnect.
- Rely on connectLoop automatic reconnection; alert only on persistent failure.
- Investigate NAT/load-balancer idle timeouts if drops occur after long silence.
Example fix
null
Defensive patterns
Strategy: retry
Validate before calling
if time.Since(p.lastPong) > pongTimeout { forceReconnect() } // detect half-open connections before reads fail Type guard
null
Try / catch
err := platform.Start(ctx)
if err != nil && strings.Contains(err.Error(), "read:") {
// transport drop; connectLoop reconnects — only alert if persistent
if consecutiveFailures > threshold { alert() }
} Prevention
- Keep websocket heartbeat/pong keepalive enabled and tuned below NAT idle timeouts
- Avoid routing long-lived wss through aggressive proxies
- Distinguish clean server close codes from abnormal 1006 drops
- Alert on reconnect loops, not single read errors
When it happens
Trigger: Server closes the connection (close frame, EOF), network drops mid-frame, read deadline/pong timeout expires, or p.ctx cancellation interrupting the read.
Common situations: Idle connection reaped by a load balancer (mitigated by the heartbeat/pong mechanism); WeCom server maintenance restart; laptop sleep/network switch; proxy closing long-lived websocket connections.
Related errors
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/3585aa8e4a29b1ee.
Report an issue: GitHub.