fish2018/pansou · error
[susu] 搜索请求返回状态码
Error message
[susu] 搜索请求返回状态码: %d
What it means
doSearch throws this when the retried search request succeeded at the transport level but the server answered with a status code other than 200 OK. The plugin treats any non-200 as a failed search and surfaces the raw status code so the caller can distinguish 403 (bot blocking), 404, 429 (rate limit), 5xx, etc. The response body is discarded without parsing.
Solutions
- Log/check the numeric status in the message: 403/503 often mean bot protection — verify setBrowserHeaders/getRandomUA produce plausible browser headers.
- If 429, back off and reduce search frequency or add rate limiting between calls.
- If 5xx, retry later; the site is having issues.
- Confirm BaseURL is current — a stale domain can return unexpected codes (e.g. parking pages).
- Consider extending doRequestWithRetry to also retry on 5xx/429 responses, not only transport errors.
Example fix
null
Defensive patterns
Strategy: retry
Try / catch
links, err := p.Search(query)
if err != nil {
var statusErr interface{ Error() string }
if strings.Contains(err.Error(), "状态码: 403") || strings.Contains(err.Error(), "状态码: 429") {
// honor backoff / rotate headers before retry
}
} Prevention
- Keep browser-like headers/UA fresh to avoid WAF blocks
- Rate-limit searches to avoid 429s
- Alert on sustained non-200 responses (site outage or endpoint drift)
- Retry only on 5xx/429, fail fast on 4xx
When it happens
Trigger: doSearch receives resp.StatusCode != http.StatusOK after doRequestWithRetry returns a response — e.g. Cloudflare/WAF challenge page (403), rate limiting (429), maintenance (503), or a redirect to an error page.
Common situations: The site's anti-bot protection flagging the request (missing/expired cookies or UA); too-frequent searches from one IP; the site being partially down; Cloudflare returning 5xx during outages.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/04739c8a3a63c5b2.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/susu/susu.go:165
defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, searchURL, nil)
if err != nil {
return nil, fmt.Errorf("创建请求失败: %w", err)
}
// 设置请求头
req.Header.Set("User-Agent", getRandomUA())
setBrowserHeaders(req, BaseURL+"/")
// 发送请求(带重试)
resp, err := p.doRequestWithRetry(client, req, MaxRetries)
if err != nil {
return nil, fmt.Errorf("请求失败: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("[susu] 搜索请求返回状态码: %d", resp.StatusCode)
}
// 解析HTML
doc, err := goquery.NewDocumentFromReader(resp.Body)
if err != nil {
return nil, fmt.Errorf("解析HTML失败: %w", err)
}
// 提取搜索结果
var wg sync.WaitGroup
resultChan := make(chan model.SearchResult, 20)
// 创建信号量控制并发数
semaphore := make(chan struct{}, MaxConcurrency)
// 预先收集所有需要处理的项
var items []*goquery.Selection
View on GitHub (pinned to beaa561337)