{"record":{"id":"e2772b878f3a29a9","repo":"chenhg5/cc-connect","slug":"qq-http-s-failed-w","errorCode":null,"errorMessage":"qq: HTTP %s failed: %w","messagePattern":"qq: HTTP (.+?) failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/qq/qq.go","lineNumber":610,"sourceCode":"\t\treturn nil, fmt.Errorf(\"qq: http_url not configured\")\n\t}\n\tbody, err := json.Marshal(params)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\turl := p.httpURL + \"/\" + action\n\treq, err := http.NewRequest(\"POST\", url, bytes.NewReader(body))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tif p.token != \"\" {\n\t\treq.Header.Set(\"Authorization\", \"Bearer \"+p.token)\n\t}\n\tclient := &http.Client{Timeout: 120 * time.Second}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"qq: HTTP %s failed: %w\", action, err)\n\t}\n\tdefer resp.Body.Close()\n\n\traw, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"qq: HTTP %s read body: %w\", action, err)\n\t}\n\n\tvar apiResp struct {\n\t\tStatus  string          `json:\"status\"`\n\t\tRetCode int             `json:\"retcode\"`\n\t\tData    json.RawMessage `json:\"data\"`\n\t\tMessage string          `json:\"message\"`\n\t}\n\tif json.Unmarshal(raw, &apiResp) != nil {\n\t\treturn nil, fmt.Errorf(\"qq: HTTP %s invalid response\", action)\n\t}\n\tif apiResp.RetCode != 0 {","sourceCodeStart":592,"sourceCodeEnd":628,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/qq/qq.go#L592-L628","documentation":"This error is returned by callHTTPAPI when the Go HTTP client fails to execute the OneBot-style HTTP API request to the QQ server (client.Do returned an error). It wraps the underlying transport error, so the root cause (DNS failure, connection refused, timeout, TLS error) is in the wrapped chain. It means the request never got a valid HTTP response, not that the server rejected it.","triggerScenarios":"Any callHTTPAPI invocation (e.g. via parseMessage) where http.Client.Do fails: server unreachable, wrong host/port in config, 120s timeout exceeded, TLS handshake failure, or no network.","commonSituations":"QQ bot HTTP server (OneBot/go-cqhttp) not running or listening on a different port; DNS misconfiguration; firewall blocking the endpoint; server hanging past the 120s client timeout; transient network outage.","solutions":["Verify the QQ OneBot HTTP endpoint host/port in config and that the server is running (curl the endpoint manually).","Inspect the wrapped %w error in logs to identify DNS vs connection vs timeout root cause.","If timeouts occur, check server responsiveness or raise/retry; the client timeout is fixed at 120s in callHTTPAPI.","Check firewall/proxy settings between cc-connect and the QQ HTTP server."],"exampleFix":"// before\nresp, err := client.Do(req)\nif err != nil {\n    return nil, fmt.Errorf(\"qq: HTTP %s failed: %w\", action, err)\n}\n// after (retry once on transient transport failure)\nresp, err := client.Do(req)\nif err != nil {\n    resp, err = client.Do(req)\n}\nif err != nil {\n    return nil, fmt.Errorf(\"qq: HTTP %s failed: %w\", action, err)\n}","handlingStrategy":"retry","validationCode":"// Go: check endpoint reachability before calling the library\nconn, err := net.DialTimeout(\"tcp\", \"127.0.0.1:5700\", 3*time.Second)\nif err != nil { return fmt.Errorf(\"qq endpoint unreachable: %w\", err) }\nconn.Close()","typeGuard":null,"tryCatchPattern":"if err != nil {\n    var netErr net.Error\n    if errors.As(err, &netErr) && netErr.Timeout() {\n        // retry with backoff\n    }\n    return fmt.Errorf(\"qq api transport error: %w\", err)\n}","preventionTips":["Confirm the OneBot HTTP endpoint URL/port in config.toml with curl before startup.","Monitor the QQ server process and restart it automatically if it crashes.","Avoid proxies/firewalls between cc-connect and the local QQ HTTP server."],"tags":["network","http-client","qq","transport-error"],"backgroundTag":"http-request-failed","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}