fish2018/pansou · error
搜索响应状态码异常
Error message
搜索响应状态码异常: %d
What it means
The libvio plugin's searchImpl aborts when the search HTTP response does not return status 200. The plugin treats any non-OK status as an unusable search response and returns this wrapped error containing the actual status code. It exists to surface upstream site problems (anti-bot, rate limiting, redirects) instead of parsing a garbage body.
Solutions
- Check the printed status code and fetch the search URL manually with curl and a browser User-Agent to reproduce
- Add/refresh browser-like headers (User-Agent, Referer, Accept) on the http.Request in searchImpl
- Slow down requests or add backoff/retry for 429/5xx responses
- Update the site base URL or search path if the site moved (common with mirror domains)
- Route the client through a proxy/cookie jar if the site geo-blocks or challenges the scraper
Example fix
// before
req, _ := http.NewRequest("GET", searchURL, nil)
resp, err := client.Do(req)
// after
req, _ := http.NewRequest("GET", searchURL, nil)
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)")
req.Header.Set("Referer", "https://libvio.app/")
resp, err := client.Do(req) Defensive patterns
Strategy: try-catch
Validate before calling
// Go: pre-check via HEAD/GET before trusting search
resp, err := client.Get(searchURL)
if err != nil || resp.StatusCode != http.StatusOK {
return fmt.Errorf("libvio 不可达: status=%v err=%v", statusOf(resp), err)
} Try / catch
results, err := p.Search(keyword)
if err != nil {
if strings.Contains(err.Error(), "状态码异常") {
// surface status code to user, schedule retry with backoff
log.Printf("libvio search upstream error: %v", err)
return fallbackResults(keyword)
}
return err
} Prevention
- Send complete browser-like headers (User-Agent, Referer, Accept-Language)
- Keep the plugin's base URL updated when the site changes domains
- Throttle request rate to avoid 429
- Monitor status codes and alert on persistent 403/5xx
When it happens
Trigger: p.searchImpl issued a GET to the libvio site, the request succeeded, but resp.StatusCode != http.StatusOK (e.g. 403 from anti-bot protection, 429 rate limit, 5xx site error, or 30x redirect not followed).
Common situations: Site enabled Cloudflare/WAF challenges; plugin client not sending a browser-like User-Agent; request rate too high; site is down or path changed after a site update.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/b7ef05ef626ab0a6.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/libvio/libvio.go:140
// searchImpl 实际的搜索实现
func (p *LibvioPlugin) searchImpl(client *http.Client, keyword string, ext map[string]interface{}) ([]model.SearchResult, error) {
searchURL := fmt.Sprintf("%s%s?wd=%s&submit=", BaseURL, SearchPath, url.QueryEscape(keyword))
if p.debugMode {
log.Printf("[Libvio] 开始搜索: %s", keyword)
log.Printf("[Libvio] 搜索URL: %s", searchURL)
}
// 发送搜索请求
resp, err := p.doRequest(client, searchURL, BaseURL)
if err != nil {
return nil, fmt.Errorf("发送搜索请求失败: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("搜索响应状态码异常: %d", resp.StatusCode)
}
// 处理响应体(可能是gzip压缩的)
reader, err := p.getResponseReader(resp)
if err != nil {
return nil, err
}
// 解析HTML
doc, err := goquery.NewDocumentFromReader(reader)
if err != nil {
return nil, fmt.Errorf("解析HTML失败: %w", err)
}
// 提取搜索结果
results := p.extractSearchResults(doc, keyword)
if p.debugMode {View on GitHub (pinned to beaa561337)