fish2018/pansou · error

read response body failed

Error message

read response body failed (page %d): %w

What it means

Hunhepan plugin throws this when io.ReadAll(resp.Body) fails after receiving a response for a page. The body could not be fully read, typically because the connection was reset or closed mid-transfer. The wrapped io error is sent to errChan.

Solutions

  1. Retry the request; mid-body connection drops are usually transient.
  2. Disable HTTP keep-alive / force a fresh connection if stale-connection resets recur.
  3. Ensure resp.Body is only read once and the client has sane Transport timeouts.
  4. Log the status code alongside the error to correlate with upstream issues.

Example fix

// before
respBody, err := io.ReadAll(resp.Body)
if err != nil {
	errChan <- fmt.Errorf("read response body failed (page %d): %w", pageNum, err)
	return
}
// after
respBody, err := io.ReadAll(io.LimitReader(resp.Body, maxBodySize))
if err != nil {
	errChan <- fmt.Errorf("read response body failed (page %d): %w", pageNum, err)
	return
}
Defensive patterns

Strategy: retry

Try / catch

results, err := plugin.Search(ctx, keyword)
if err != nil && strings.Contains(err.Error(), "read response body failed") {
	// transient body read failure: retry once with a backoff
	time.Sleep(time.Second)
	results, err = plugin.Search(ctx, keyword)
}

Prevention

When it happens

Trigger: io.ReadAll(resp.Body) returns a non-nil error for page pageNum: unexpected EOF from a dropped connection, broken pipe, or read timeout on the body stream.

Common situations: Upstream server or an intermediate proxy closes the connection early; very large responses hit an idle-connection reset; keep-alive connections reused after server-side expiry.

Related errors


AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07). Data as JSON: /api/errors/933586828e109711. Report an issue: GitHub.

Appendix: source

Thrown at plugin/hunhepan/hunhepan.go:247

				req.Header.Set("Origin", "https://www.misoso.cc")
			}

			// 发送请求
			resp, err := client.Do(req)
			if err != nil {
				debugLog("请求失败 (page %d): %v", pageNum, err)
				errChan <- fmt.Errorf("request failed (page %d): %w", pageNum, err)
				return
			}
			defer resp.Body.Close()

			debugLog("收到响应 (page %d), 状态码: %d", pageNum, resp.StatusCode)

			// 读取响应体
			respBody, err := io.ReadAll(resp.Body)
			if err != nil {
				debugLog("读取响应失败 (page %d): %v", pageNum, err)
				errChan <- fmt.Errorf("read response body failed (page %d): %w", pageNum, err)
				return
			}

			debugLog("响应内容 (page %d, 前500字符): %s", pageNum, string(respBody[:min(500, len(respBody))]))

			// 解析响应
			var apiResp HunhepanResponse
			if err := json.Unmarshal(respBody, &apiResp); err != nil {
				debugLog("JSON解析失败 (page %d): %v", pageNum, err)
				errChan <- fmt.Errorf("decode response failed (page %d): %w", pageNum, err)
				return
			}

			// 检查响应状态
			if apiResp.Code != 200 {
				debugLog("API返回错误 (page %d): code=%d, msg=%s", pageNum, apiResp.Code, apiResp.Msg)
				errChan <- fmt.Errorf("API returned error (page %d): %s", pageNum, apiResp.Msg)
				return

View on GitHub (pinned to beaa561337)