fish2018/pansou · error
[ ] search request failed on page
Error message
[%s] search request failed on page %d: %w
What it means
p.scraper.Get(searchURL) failed with a transport-level error on a search page. When no results have been collected yet (allResults empty) the error is fatal and wrapped with page number and plugin name; if earlier pages succeeded, the loop just breaks with a warning since partial results are usable.
Solutions
- Check basic connectivity to panzun.cc from the host (curl the API URL)
- Retry later or increase the HTTP client timeout
- Inspect the wrapped %w cause for the underlying transport error (DNS/TLS/timeout)
- If Cloudflare blocks the request, update the cloudscraper client or use a proxy
Example fix
// before
return nil, fmt.Errorf("[%s] search request failed on page %d: %w", p.Name(), page, err)
// after
if urlErr, ok := err.(*url.Error); ok { log.Printf("transport error: %v", urlErr.Err) }
return nil, fmt.Errorf("[%s] search request failed on page %d: %w", p.Name(), page, err) // inspect wrapped cause Defensive patterns
Strategy: retry
Validate before calling
conn, err := net.DialTimeout("tcp", "www.panzun.cc:443", 5*time.Second)
if err != nil { /* upstream unreachable — skip plugin */ } else { conn.Close() } Try / catch
results, err := plugin.Search(keyword, ext)
if err != nil {
var urlErr *url.Error
if errors.As(err, &urlErr) && urlErr.Timeout() {
// transient: retry with backoff
} else {
// skip this plugin, use other providers
}
} Prevention
- Monitor upstream availability and skip plugins whose source is down
- Set realistic HTTP timeouts and retry budgets
- Use the wrapped %w error to classify DNS vs timeout vs TLS failures
When it happens
Trigger: Network failure, DNS failure, TLS error, connection timeout, or Cloudflare challenge failure while GETting https://www.panzun.cc/api/discussions?filter[q]=... on page N, with zero results collected so far.
Common situations: Target site down or blocking the client IP; no network access in the deployment environment; Cloudflare protection rejecting the cloudscraper handshake; timeout too low for a slow upstream.
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/f077cf3ff30d9730.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/panzun/panzun.go:126
func (p *PanzunPlugin) searchImpl(client *http.Client, keyword string, ext map[string]interface{}) ([]model.SearchResult, error) {
if p.scraper == nil {
return nil, fmt.Errorf("cloudscraper not initialized")
}
var allResults []model.SearchResult
seenIDs := make(map[string]bool)
for page := 1; page <= maxPages; page++ {
offset := (page - 1) * pageSize
searchURL := fmt.Sprintf("%s/discussions?filter[q]=%s&page[offset]=%d", apiBase, url.QueryEscape(keyword), offset)
resp, err := p.scraper.Get(searchURL)
if err != nil {
if len(allResults) > 0 {
fmt.Printf("[%s] Warning: failed to fetch page %d: %v\n", p.Name(), page, err)
break
}
return nil, fmt.Errorf("[%s] search request failed on page %d: %w", p.Name(), page, err)
}
if resp.StatusCode != http.StatusOK {
resp.Body.Close()
if len(allResults) > 0 {
fmt.Printf("[%s] Warning: unexpected status code %d on page %d\n", p.Name(), resp.StatusCode, page)
break
}
return nil, fmt.Errorf("[%s] unexpected status code: %d on page %d", p.Name(), resp.StatusCode, page)
}
body, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
if len(allResults) > 0 {
break
}
return nil, fmt.Errorf("[%s] failed to read response on page %d: %w", p.Name(), page, err)View on GitHub (pinned to beaa561337)