{"record":{"id":"bf740a0c3dc885cf","repo":"fish2018/pansou","slug":"w-bf740a","errorCode":null,"errorMessage":"读取响应失败: %w","messagePattern":"读取响应失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/bixin/bixin.go","lineNumber":219,"sourceCode":"\t// 重试逻辑\n\tfor i := 0; i <= p.retries; i++ {\n\t\t// 发送请求\n\t\tresp, err = client.Do(req)\n\t\tif err != nil {\n\t\t\tif i == p.retries {\n\t\t\t\treturn nil, false, fmt.Errorf(\"请求失败: %w\", err)\n\t\t\t}\n\t\t\ttime.Sleep(500 * time.Millisecond)\n\t\t\tcontinue\n\t\t}\n\t\t\n\t\tdefer resp.Body.Close()\n\t\t\n\t\t// 读取响应体\n\t\tresponseBody, err = io.ReadAll(resp.Body)\n\t\tif err != nil {\n\t\t\tif i == p.retries {\n\t\t\t\treturn nil, false, fmt.Errorf(\"读取响应失败: %w\", err)\n\t\t\t}\n\t\t\ttime.Sleep(500 * time.Millisecond)\n\t\t\tcontinue\n\t\t}\n\t\t\n\t\t// 状态码检查\n\t\tif resp.StatusCode != http.StatusOK {\n\t\t\tif i == p.retries {\n\t\t\t\treturn nil, false, fmt.Errorf(\"API返回非200状态码: %d\", resp.StatusCode)\n\t\t\t}\n\t\t\ttime.Sleep(500 * time.Millisecond)\n\t\t\tcontinue\n\t\t}\n\t\t\n\t\t// 请求成功，跳出重试循环\n\t\tbreak\n\t}\n\t","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/bixin/bixin.go#L201-L237","documentation":"fetchPage in the bixin plugin wraps errors from io.ReadAll(resp.Body) after exhausting all retry attempts. It means the response body could not be fully read — typically a connection reset or timeout mid-body, or a truncated/chunked-transfer failure. Retries were attempted (500ms apart) before giving up.","triggerScenarios":"io.ReadAll(resp.Body) returns err on the final retry iteration (i == p.retries) inside fetchPage, usually when the server closes the connection before the full body is delivered.","commonSituations":"Server-side timeouts on slow/large responses, proxy or LB terminating the connection prematurely, flaky mobile/unstable networks.","solutions":["Retry the search; if it recurs, capture the wrapped error to see if it is 'connection reset' or 'unexpected EOF'.","Check server/load-balancer health and timeouts for the bixin endpoint.","Increase client timeout and p.retries to tolerate slow responses.","Verify no proxy is truncating large response bodies."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"results, err := plugin.Search(ctx, keyword)\nif err != nil {\n    if strings.Contains(err.Error(), \"读取响应失败\") {\n        // transient body read failure: retry once, then fall back to cached results\n    }\n}","preventionTips":["Use bounded reads (io.LimitReader) to avoid unbounded waits on slow bodies","Configure client timeouts generously relative to expected body size","Retry transient read errors with backoff","Watch for proxy/LB idle-timeout settings that truncate large responses"],"tags":["network","io","http-body","retry-exhausted"],"backgroundTag":"http-request-failed","analyzedSha":"beaa56133755a548ebc51b090b3816e2ae044aa6","analyzedAt":"2026-09-07T00:31:18.025Z","contentChangedAt":"2026-09-07T00:31:18.025Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}