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

  1. Retry the request — transient connection resets are common; doRequestWithRetry already retried the initial Do but not the body read.
  2. Increase TimeoutSeconds if large pages exceed the deadline during body transfer.
  3. Check for TLS-intercepting proxies/firewalls truncating responses; test with curl --compressed from the same host.
  4. Set a bound read (io.LimitReader) if huge responses are a concern, and log body-read progress for large pages.
  5. 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

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)