fish2018/pansou · error
重试 次后仍然失败
Error message
重试 %d 次后仍然失败: %w
What it means
This error is returned by doRequestWithRetry in the aikanzy plugin after all HTTP request attempts to the aikanzy site have failed. It wraps the last underlying error (via %w) so the real cause — timeout, DNS failure, connection reset, non-retryable client error, etc. — is preserved. It signals that even after maxRetries attempts with backoff, no successful response was obtained.
Solutions
- Inspect the wrapped cause with errors.Unwrap / %v of the error and fix that root problem (timeout vs DNS vs status code).
- Verify network egress to the target site (curl the URL from the same host, check proxy env vars HTTP_PROXY/HTTPS_PROXY).
- Increase maxRetries or retry backoff in doRequestWithRetry if failures are transient (rate limiting, occasional 5xx).
- Raise the request context timeout if errors are context deadline exceeded.
- Check whether the site changed its URL/blocked scrapers; update the base URL or headers if so.
Example fix
// before
results, err := p.doSearch(keyword)
// after
results, err := p.doSearch(keyword)
if errors.Is(err, context.DeadlineExceeded) {
// extend per-attempt timeout or reduce result scope and retry
}
if err != nil {
log.Printf("aikanzy unavailable, continuing with other plugins: %v", err)
} Defensive patterns
Strategy: retry
Validate before calling
// Pre-check reachability before invoking the plugin
resp, err := http.Head("https://aikanzy.example.com")
if err != nil {
log.Printf("aikanzy unreachable, skipping: %v", err)
} Try / catch
// Go: inspect the wrapped cause and degrade gracefully
results, err := plugin.Search(keyword, ext)
if err != nil {
var ctxErr error
if errors.Is(err, context.DeadlineExceeded) {
ctxErr = fmt.Errorf("aikanzy timed out: %w", err)
}
log.Printf("skipping aikanzy results: %v", err)
results = nil // continue with other plugins
} Prevention
- Monitor site reachability and alert before retries start failing consistently.
- Keep per-request timeouts comfortably above worst-case latency.
- Cap retry storms: increase backoff instead of only increasing retry count.
- Respect rate limits to avoid getting blocked and burning all retries.
When it happens
Trigger: Any caller of doRequestWithRetry (doSearch, fetchDetailPageLinks) exhausts maxRetries because the site is unreachable, times out, refuses connections, or returns errors the retry loop does not tolerate on every attempt.
Common situations: The aikanzy site is down or blocked from the deployment network; DNS resolution fails; the per-request context deadline expires; the site rate-limits or returns 4xx/5xx on every attempt; a proxy/firewall drops the connections.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/bcc6484b15d180f5.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/aikanzy/aikanzy.go:592
// 指数退避
backoffTime := time.Duration(1<<uint(retry-1)) * backoffBase * time.Millisecond
time.Sleep(backoffTime)
// 克隆请求
req = req.Clone(req.Context())
}
resp, err = client.Do(req)
if err == nil && resp.StatusCode == 200 {
return resp, nil
}
if resp != nil {
resp.Body.Close()
}
}
return nil, fmt.Errorf("重试 %d 次后仍然失败: %w", maxRetries, err)
}
View on GitHub (pinned to beaa561337)