fish2018/pansou · error

请求失败,已重试 次

Error message

请求失败,已重试%d次: %w

What it means

ClmaoPlugin.doRequestWithRetry has exhausted all MaxRetries attempts for an HTTP request without success. Each failed attempt records lastErr and sleeps i+1 seconds between attempts (linear backoff). After the final failure it returns this aggregate error wrapping the last transport error. Called from searchPage and fetchModernDetail, so both search and modern-detail fetching surface this on connectivity problems.

Solutions

  1. Unwrap the error chain to find lastErr's actual cause (timeout vs connection refused vs TLS).
  2. Verify outbound connectivity/DNS from the deployment environment (curl the endpoint).
  3. Increase TimeoutSeconds if each attempt times out; adjust MaxRetries/backoff to fit the endpoint's reliability.
  4. Update headers in setRequestHeaders (User-Agent, cookies) if the site started blocking the client.
  5. Add exponential backoff with jitter and honor Retry-After if failures correlate with rate limiting.

Example fix

// before
time.Sleep(time.Duration(i+1) * time.Second)
// after
backoff := time.Duration(1<<uint(i)) * time.Second
backoff += time.Duration(rand.Int63n(int64(time.Second))) // jitter
time.Sleep(backoff)
Defensive patterns

Strategy: retry

Validate before calling

func canReach(target string) bool {
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    req, err := http.NewRequestWithContext(ctx, http.MethodGet, target, nil)
    if err != nil { return false }
    resp, err := http.DefaultClient.Do(req)
    if err != nil { return false }
    resp.Body.Close()
    return true
}

Try / catch

resp, err := p.doRequestWithRetry(req, client)
if err != nil {
    var netErr net.Error
    if errors.As(err, &netErr) && netErr.Timeout() { /* escalate timeout or circuit-break */ }
    return nil, fmt.Errorf("clmao transport failure after retries: %w", err)
}

Prevention

When it happens

Trigger: Any HTTP request issued via p.doRequestWithRetry fails on every one of MaxRetries attempts — network unreachable, DNS failure, connection reset, TLS error, or each attempt's context deadline (TimeoutSeconds) expiring. After the loop with no success: fmt.Errorf("请求失败,已重试%d次: %w", MaxRetries, lastErr).

Common situations: The clmao site is down or geo-blocked; anti-bot measures drop connections from non-browser clients; the host has no internet/DNS in containers or CI; TimeoutSeconds too short so every attempt times out.

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/4323e6599dfae982. Report an issue: GitHub.

Appendix: source

Thrown at plugin/clmao/clmao.go:532

}

// doRequestWithRetry 带重试的HTTP请求
func (p *ClmaoPlugin) doRequestWithRetry(req *http.Request, client *http.Client) (*http.Response, error) {
	var lastErr error

	for i := 0; i < MaxRetries; i++ {
		resp, err := client.Do(req)
		if err == nil {
			return resp, nil
		}

		lastErr = err
		if i < MaxRetries-1 {
			time.Sleep(time.Duration(i+1) * time.Second)
		}
	}

	return nil, fmt.Errorf("请求失败,已重试%d次: %w", MaxRetries, lastErr)
}

// init 注册插件
func init() {
	plugin.RegisterGlobalPlugin(NewClmaoPlugin())
}

View on GitHub (pinned to beaa561337)