{"record":{"id":"4e2dba31eec13299","repo":"chenhg5/cc-connect","slug":"ws-connect-w","errorCode":null,"errorMessage":"ws connect: %w","messagePattern":"ws connect: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"platform/qqbot/qqbot.go","lineNumber":650,"sourceCode":"// WebSocket Gateway\n// ---------------------------------------------------------------------------\n\nfunc (p *Platform) connectGateway(ctx context.Context) error {\n\ttoken, err := p.getAccessToken()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Get gateway URL\n\tgatewayURL, err := p.getGatewayURL(token)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Connect WebSocket\n\tconn, _, err := websocket.DefaultDialer.Dial(gatewayURL, nil)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"ws connect: %w\", err)\n\t}\n\n\tp.wsMu.Lock()\n\tp.wsConn = conn\n\tp.wsMu.Unlock()\n\n\t// Wait for Hello (op 10)\n\tif err := p.waitForHello(conn); err != nil {\n\t\tconn.Close()\n\t\treturn err\n\t}\n\n\t// Send Identify (op 2)\n\tif err := p.sendIdentify(conn, token); err != nil {\n\t\tconn.Close()\n\t\treturn err\n\t}\n","sourceCodeStart":632,"sourceCodeEnd":668,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/qqbot/qqbot.go#L632-L668","documentation":"Returned by the QQ bot WebSocket connect step when websocket.DefaultDialer.Dial fails to establish a TCP+TLS connection to the gateway URL obtained from the QQ gateway API. The error wraps the underlying dial error (DNS failure, TLS handshake, timeout, refused connection). Platform startup aborts because the WS link is mandatory for receiving events.","triggerScenarios":"Dial(gatewayURL) fails: network down, DNS cannot resolve the gateway host, proxy/firewall blocks wss://, or the gateway URL from the API is malformed/unreachable.","commonSituations":"Running on an isolated server/CI without outbound HTTPS to QQ servers; corporate firewall blocking WebSocket upgrades; transient QQ gateway outage; wrong system proxy settings.","solutions":["Verify outbound network access: curl the gateway URL host from the same machine","Check proxy env vars (HTTP_PROXY/HTTPS_PROXY) are correct if behind a proxy","Re-check that getGatewayURL succeeded and the appid/secret are valid so a real gateway URL is returned","Retry with backoff — gateway outages are usually transient"],"exampleFix":"// before\nconn, _, err := websocket.DefaultDialer.Dial(gatewayURL, nil)\n// after\ndialer := websocket.DefaultDialer\ndialer.HandshakeTimeout = 10 * time.Second\nconn, _, err := dialer.Dial(gatewayURL, nil)\nif err != nil {\n    return fmt.Errorf(\"ws connect: %w\", err)\n}","handlingStrategy":"retry","validationCode":"u, err := url.Parse(gatewayURL)\nif err != nil || u.Scheme != \"wss\" && u.Scheme != \"ws\" {\n    return fmt.Errorf(\"bad gateway URL: %v\", err)\n}","typeGuard":null,"tryCatchPattern":"for attempt := 0; attempt < 5; attempt++ {\n    if err := connectWS(); err != nil {\n        if errors.Is(err, syscall.ECONNREFUSED) {\n            time.Sleep(backoff(attempt)); continue\n        }\n        return err\n    }\n    break\n}","preventionTips":["Health-check outbound connectivity to QQ hosts before starting the bot","Set an explicit dialer handshake timeout","Monitor gateway URL fetch failures separately from dial failures"],"tags":["websocket","network","qqbot"],"backgroundTag":"connection-refused","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}