fish2018/pansou · error
读取响应失败
Error message
读取响应失败: %w
What it means
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.
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.
Defensive patterns
Strategy: retry
Try / catch
results, err := plugin.Search(ctx, keyword)
if err != nil {
if strings.Contains(err.Error(), "读取响应失败") {
// transient body read failure: retry once, then fall back to cached results
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: Server-side timeouts on slow/large responses, proxy or LB terminating the connection prematurely, flaky mobile/unstable networks.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/bf740a0c3dc885cf.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/bixin/bixin.go:219
// 重试逻辑
for i := 0; i <= p.retries; i++ {
// 发送请求
resp, err = client.Do(req)
if err != nil {
if i == p.retries {
return nil, false, fmt.Errorf("请求失败: %w", err)
}
time.Sleep(500 * time.Millisecond)
continue
}
defer resp.Body.Close()
// 读取响应体
responseBody, err = io.ReadAll(resp.Body)
if err != nil {
if i == p.retries {
return nil, false, fmt.Errorf("读取响应失败: %w", err)
}
time.Sleep(500 * time.Millisecond)
continue
}
// 状态码检查
if resp.StatusCode != http.StatusOK {
if i == p.retries {
return nil, false, fmt.Errorf("API返回非200状态码: %d", resp.StatusCode)
}
time.Sleep(500 * time.Millisecond)
continue
}
// 请求成功,跳出重试循环
break
}
View on GitHub (pinned to beaa561337)