fish2018/pansou · error
读取响应失败
Error message
读取响应失败: %w
What it means
pan666's fetchPage returns this when io.ReadAll(resp.Body) fails on the last retry. A response was received but the body stream broke mid-read — connection reset, premature close, or transfer interrupted. Earlier attempts retry after 500ms; the final one surfaces the io error wrapped.
Solutions
- Retry — this class of error is usually transient
- Check network path stability (proxy, VPN, firewall) between client and pan666 API
- Confirm the server isn't closing connections early (curl -v, check Content-Length vs received bytes)
- Disable aggressive connection reuse/keep-alive tuning if stale sockets cause resets
Example fix
// before
responseBody, err = io.ReadAll(resp.Body)
if err != nil {
if i == p.retries { return nil, false, fmt.Errorf("读取响应失败: %w", err) }
// after
responseBody, err = io.ReadAll(io.LimitReader(resp.Body, 10<<20))
if err != nil {
if errors.Is(err, io.ErrUnexpectedEOF) && i < p.retries { time.Sleep(500 * time.Millisecond); continue } Defensive patterns
Strategy: retry
Try / catch
if err != nil {
if errors.Is(err, io.ErrUnexpectedEOF) {
time.Sleep(1 * time.Second)
return fetchPageRetry(offset) // full re-fetch; partial body is unusable
}
return err
} Prevention
- Never parse partial bodies — always refetch on read error
- Use io.LimitReader to cap body size
- Prefer fresh connections over reused keep-alive sockets when resets recur
- Monitor truncation rates to detect upstream instability
When it happens
Trigger: After a successful client.Do, reading the body fails with io.ErrUnexpectedEOF, connection reset by peer, or similar — server/proxy killed the connection before the full body arrived, on every retry.
Common situations: Unstable upstream or CDN dropping large responses; middlebox truncating keep-alive connections; server under load closing connections early; VPN/proxy link flapping.
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/7e12f685321e7ee0.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/pan666/pan666.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)