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

  1. Retry the search; if it recurs, capture the wrapped error to see if it is 'connection reset' or 'unexpected EOF'.
  2. Check server/load-balancer health and timeouts for the bixin endpoint.
  3. Increase client timeout and p.retries to tolerate slow responses.
  4. 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

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)