{"record":{"id":"933586828e109711","repo":"fish2018/pansou","slug":"read-response-body-failed-page-d-w","errorCode":null,"errorMessage":"read response body failed (page %d): %w","messagePattern":"read response body failed \\(page (.+?)\\): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/hunhepan/hunhepan.go","lineNumber":247,"sourceCode":"\t\t\t\treq.Header.Set(\"Origin\", \"https://www.misoso.cc\")\n\t\t\t}\n\n\t\t\t// 发送请求\n\t\t\tresp, err := client.Do(req)\n\t\t\tif err != nil {\n\t\t\t\tdebugLog(\"请求失败 (page %d): %v\", pageNum, err)\n\t\t\t\terrChan <- fmt.Errorf(\"request failed (page %d): %w\", pageNum, err)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tdefer resp.Body.Close()\n\n\t\t\tdebugLog(\"收到响应 (page %d), 状态码: %d\", pageNum, resp.StatusCode)\n\n\t\t\t// 读取响应体\n\t\t\trespBody, err := io.ReadAll(resp.Body)\n\t\t\tif err != nil {\n\t\t\t\tdebugLog(\"读取响应失败 (page %d): %v\", pageNum, err)\n\t\t\t\terrChan <- fmt.Errorf(\"read response body failed (page %d): %w\", pageNum, err)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tdebugLog(\"响应内容 (page %d, 前500字符): %s\", pageNum, string(respBody[:min(500, len(respBody))]))\n\n\t\t\t// 解析响应\n\t\t\tvar apiResp HunhepanResponse\n\t\t\tif err := json.Unmarshal(respBody, &apiResp); err != nil {\n\t\t\t\tdebugLog(\"JSON解析失败 (page %d): %v\", pageNum, err)\n\t\t\t\terrChan <- fmt.Errorf(\"decode response failed (page %d): %w\", pageNum, err)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// 检查响应状态\n\t\t\tif apiResp.Code != 200 {\n\t\t\t\tdebugLog(\"API返回错误 (page %d): code=%d, msg=%s\", pageNum, apiResp.Code, apiResp.Msg)\n\t\t\t\terrChan <- fmt.Errorf(\"API returned error (page %d): %s\", pageNum, apiResp.Msg)\n\t\t\t\treturn","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/hunhepan/hunhepan.go#L229-L265","documentation":"Hunhepan plugin throws this when io.ReadAll(resp.Body) fails after receiving a response for a page. The body could not be fully read, typically because the connection was reset or closed mid-transfer. The wrapped io error is sent to errChan.","triggerScenarios":"io.ReadAll(resp.Body) returns a non-nil error for page pageNum: unexpected EOF from a dropped connection, broken pipe, or read timeout on the body stream.","commonSituations":"Upstream server or an intermediate proxy closes the connection early; very large responses hit an idle-connection reset; keep-alive connections reused after server-side expiry.","solutions":["Retry the request; mid-body connection drops are usually transient.","Disable HTTP keep-alive / force a fresh connection if stale-connection resets recur.","Ensure resp.Body is only read once and the client has sane Transport timeouts.","Log the status code alongside the error to correlate with upstream issues."],"exampleFix":"// before\nrespBody, err := io.ReadAll(resp.Body)\nif err != nil {\n\terrChan <- fmt.Errorf(\"read response body failed (page %d): %w\", pageNum, err)\n\treturn\n}\n// after\nrespBody, err := io.ReadAll(io.LimitReader(resp.Body, maxBodySize))\nif err != nil {\n\terrChan <- fmt.Errorf(\"read response body failed (page %d): %w\", pageNum, err)\n\treturn\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"results, err := plugin.Search(ctx, keyword)\nif err != nil && strings.Contains(err.Error(), \"read response body failed\") {\n\t// transient body read failure: retry once with a backoff\n\ttime.Sleep(time.Second)\n\tresults, err = plugin.Search(ctx, keyword)\n}","preventionTips":["Retry transient mid-body connection drops with exponential backoff","Bound response size with io.LimitReader to avoid long transfers on flaky networks","Keep Transport idle-connection settings sane to avoid stale-connection resets","Watch for recurring failures that indicate an unstable upstream or proxy"],"tags":["network","io","go","response-body"],"backgroundTag":"broken-pipe","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"}