fish2018/pansou · error
读取详情页响应失败
Error message
读取详情页响应失败: %w
What it means
fetchMagnetLink reads the entire detail-page response body with io.ReadAll and this error wraps any read failure — the response body is a network stream, so this is usually a mid-transfer connection drop, timeout, or decompression error rather than a disk problem.
Solutions
- Retry the request — transient connection resets are common; doRequestWithRetry already retried the initial Do but not the body read.
- Increase TimeoutSeconds if large pages exceed the deadline during body transfer.
- Check for TLS-intercepting proxies/firewalls truncating responses; test with curl --compressed from the same host.
- Set a bound read (io.LimitReader) if huge responses are a concern, and log body-read progress for large pages.
- If Content-Encoding mismatch is suspected, verify the client's Transport has automatic decompression enabled (Accept-Encoding handling).
Example fix
// before
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("读取详情页响应失败: %w", err)
}
// after
body, err := io.ReadAll(io.LimitReader(resp.Body, maxBodySize))
if err != nil {
if errors.Is(err, context.DeadlineExceeded) {
return "", fmt.Errorf("detail body read timed out for %s: %w", detailURL, err)
}
return "", fmt.Errorf("读取详情页响应失败: %w", err)
} Defensive patterns
Strategy: retry
Try / catch
magnet, err := p.fetchMagnetLink(client, detailURL)
if err != nil && strings.Contains(err.Error(), "读取详情页响应失败") {
// transient body read failure: retry once after short delay
time.Sleep(time.Second)
magnet, err = p.fetchMagnetLink(client, detailURL)
} Prevention
- Retry body reads — mid-transfer resets are usually transient
- Use io.LimitReader to bound response size
- Ensure automatic gzip handling in http.Transport
- Increase timeout for large pages
When it happens
Trigger: io.ReadAll(resp.Body) fails while streaming the detail page: connection reset by peer mid-response, the TimeoutSeconds context deadline expiring during body transfer, gzip/deflate decode errors, or chunked-encoding corruption.
Common situations: Slow or unstable network to the target site; server closing connections early under load or anti-bot measures; proxy/CDN terminating long responses; the response being gzip-encoded but the decompressor rejecting it.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/2b87fc023f0538a7.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/wuji/wuji.go:329
// 设置请求头
p.setRequestHeaders(req)
// 发送HTTP请求
resp, err := p.doRequestWithRetry(req, client)
if err != nil {
return "", fmt.Errorf("详情页请求失败: %w", err)
}
defer resp.Body.Close()
// 检查状态码
if resp.StatusCode != 200 {
return "", fmt.Errorf("详情页返回状态码: %d", resp.StatusCode)
}
// 读取响应体内容
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("读取详情页响应失败: %w", err)
}
// 解析HTML
doc, err := goquery.NewDocumentFromReader(strings.NewReader(string(body)))
if err != nil {
return "", fmt.Errorf("详情页HTML解析失败: %w", err)
}
// 提取磁力链接
magnetInput := doc.Find("input#input-magnet")
if magnetInput.Length() == 0 {
return "", fmt.Errorf("未找到磁力链接输入框")
}
magnetLink, exists := magnetInput.Attr("value")
if !exists || magnetLink == "" {
return "", fmt.Errorf("磁力链接为空")
}View on GitHub (pinned to beaa561337)