fish2018/pansou · warning

HTTP 状态码

Error message

HTTP 状态码 %d

What it means

Inside doJuPansouRequestWithRetry's retry loop, when an attempt ends with a nil error but a non-2xx status, lastErr is set to this synthetic "HTTP 状态码 %d" error so the final retry-exhausted error carries the status. It records that the server answered with a rejected status code on the last attempt.

Solutions

  1. Read the recorded status code in the final wrapped error to know why retries failed.
  2. Reduce request rate if the code is 429; add jitter to backoff.
  3. Improve headers/cookies if the code is 403 (anti-bot).
  4. Check upstream health for persistent 5xx.
  5. Increase jupansouMaxRetries for bursty transient errors.
Defensive patterns

Strategy: retry

Try / catch

_, err := p.search(client, keyword)
if err != nil && strings.Contains(err.Error(), "HTTP 状态码 429") {
    time.Sleep(time.Minute) // honor rate limit before next call
}

Prevention

When it happens

Trigger: An attempt in the retry loop receives a response whose status code triggered the retry path (e.g. 429/503), so lastErr is set to `HTTP 状态码 %d` before backoff and the next attempt.

Common situations: Rate limiting (429) from polling too fast; temporary upstream overload (503); WAF responses (403) on some attempts that alternate with failures.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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

Appendix: source

Thrown at plugin/jupansou/jupansou.go:334

			return value
		}
	}
	return ""
}

func doJuPansouRequestWithRetry(req *http.Request, client *http.Client) (*http.Response, error) {
	var lastErr error
	for attempt := 0; attempt < jupansouMaxRetries; attempt++ {
		resp, err := client.Do(req.Clone(req.Context()))
		if err == nil && resp.StatusCode == http.StatusOK {
			return resp, nil
		}
		if resp != nil {
			resp.Body.Close()
		}
		lastErr = err
		if lastErr == nil {
			lastErr = fmt.Errorf("HTTP 状态码 %d", resp.StatusCode)
		}
		if attempt < jupansouMaxRetries-1 {
			time.Sleep(200 * time.Millisecond * time.Duration(1<<attempt))
		}
	}
	return nil, fmt.Errorf("重试 %d 次后失败: %w", jupansouMaxRetries, lastErr)
}

View on GitHub (pinned to beaa561337)