{"record":{"id":"b7db707ab7088ec5","repo":"fish2018/pansou","slug":"read-response-body-failed-w","errorCode":null,"errorMessage":"read response body failed: %w","messagePattern":"read response body failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/jikepan/jikepan.go","lineNumber":93,"sourceCode":"\t\treturn nil, fmt.Errorf(\"create request failed: %w\", err)\n\t}\n\t\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"referer\", \"https://jikepan.xyz/\")\n\treq.Header.Set(\"User-Agent\", \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36\")\n\t\n\t// 发送请求\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"request failed: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\t\n\t// 解析响应\n\tvar apiResp JikepanResponse\n\tbodyBytes, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"read response body failed: %w\", err)\n\t}\n\t\n\tif err := json.Unmarshal(bodyBytes, &apiResp); err != nil {\n\t\treturn nil, fmt.Errorf(\"decode response failed: %w\", err)\n\t}\n\t\n\t// 检查响应状态\n\tif apiResp.Msg != \"success\" {\n\t\treturn nil, fmt.Errorf(\"API returned error: %s\", apiResp.Msg)\n\t}\n\t\n\t// 转换结果格式\n\tresults := p.convertResults(apiResp.List)\n\t\n\treturn results, nil\n}\n\n// convertResults 将API响应转换为标准SearchResult格式","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/jikepan/jikepan.go#L75-L111","documentation":"After the API responds, doSearch reads the entire response body with io.ReadAll. If the body cannot be read (connection dropped mid-response, read timeout, aborted transfer), the error is wrapped as \"read response body failed\".","triggerScenarios":"io.ReadAll(resp.Body) errors while draining the Jikepan API response: server closes connection early, network interruption mid-transfer, or read deadline exceeded.","commonSituations":"Unstable network/mobile connections; Jikepan server or an intermediary proxy truncating responses; very large responses hitting a client read timeout; TLS termination issues.","solutions":["Inspect the wrapped error for \"unexpected EOF\" vs timeout to pick the fix","Retry the request on transient read errors","Check proxy/LB idle timeouts versus response time","Consider limiting response size with io.LimitReader to fail fast on anomalies"],"exampleFix":"// before\nbodyBytes, err := io.ReadAll(resp.Body)\nif err != nil {\n\treturn nil, fmt.Errorf(\"read response body failed: %w\", err)\n}\n\n// after\nbodyBytes, err := io.ReadAll(io.LimitReader(resp.Body, 10<<20))\nif err != nil {\n\treturn nil, fmt.Errorf(\"read response body failed (status %d): %w\", resp.StatusCode, err)\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Go\nresults, err := p.doSearch(ctx, keyword, ext)\nif err != nil && strings.Contains(err.Error(), \"read response body failed\") {\n\t// transient read failure: retry once with backoff\n}","preventionTips":["Use io.LimitReader to bound response size","Ensure client timeouts exceed slow-response times","Check intermediary proxy idle timeouts","Prefer HTTP/2 or keep-alive for stable connections"],"tags":["network","io","http-response"],"backgroundTag":"network-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"}