fish2018/pansou · error
[ ] 请求返回状态码
Error message
[%s] 请求返回状态码: %d
What it means
The kkv plugin rejects any search response whose HTTP status is not 200. After retries succeeded at the transport level, the server returned a non-200 status (e.g. 403 anti-bot, 404 wrong path, 5xx). The plugin treats this as a search failure rather than trying to parse the body.
Solutions
- Log resp.StatusCode (the message already contains it) and check which status it is before changing anything
- For 403/429: add realistic headers/cookies via setHeaders, slow down request rate, or route through a residential proxy
- For 404: inspect the site and update the search URL pattern in the plugin
- For 5xx: retry later; the upstream site is degraded
Defensive patterns
Strategy: try-catch
Try / catch
results, err := plugin.Search(ctx, kw)
if err != nil {
var statusErr interface{ HTTPStatus() int } // or match the '[%s] 请求返回状态码: %d' text
if strings.Contains(err.Error(), "请求返回状态码") {
// non-200 from upstream: fall back to another source instead of failing the request
return fallbackSource.Search(ctx, kw)
}
return err
} Prevention
- Throttle request rate per source to avoid 429 bans
- Route through residential proxies when datacenter IPs get 403s
- Monitor status codes per source and alert on rising 403/5xx rates
- Keep source URL patterns updated when sites redesign
When it happens
Trigger: doRequestWithRetry returns a response whose resp.StatusCode != 200 for the kkv search URL — most commonly 403 from anti-scraping (Cloudflare), 404 after the site changed its URL structure, or 5xx while the site is degraded.
Common situations: Cloudflare/WAF blocking datacenter IPs (403/429), the source site changed its search path so the old URL 404s, rate limiting after heavy scraping, site maintenance returning 503.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/f0e37a08d70d64a8.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/kkv/kkv.go:137
defer cancel()
req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil)
if err != nil {
return nil, fmt.Errorf("[%s] 创建请求失败: %w", p.Name(), err)
}
p.setHeaders(req, baseURL)
resp, err := p.doRequestWithRetry(req, client)
if err != nil {
return nil, fmt.Errorf("[%s] 搜索请求失败: %w", p.Name(), err)
}
defer resp.Body.Close()
debugPrintf("📡 HTTP状态码: %d\n", resp.StatusCode)
if resp.StatusCode != 200 {
return nil, fmt.Errorf("[%s] 请求返回状态码: %d", p.Name(), resp.StatusCode)
}
doc, err := goquery.NewDocumentFromReader(resp.Body)
if err != nil {
return nil, fmt.Errorf("[%s] HTML解析失败: %w", p.Name(), err)
}
var items []searchItem
doc.Find("article.post").Each(func(i int, s *goquery.Selection) {
link := s.Find(".entry-header h2.entry-title a")
href, exists := link.Attr("href")
if !exists {
debugPrintf("⚠️ 第%d个结果没有href属性\n", i+1)
return
}
title := strings.TrimSpace(link.Text())
if title == "" {View on GitHub (pinned to beaa561337)