fish2018/pansou · error
[ ] 请求返回状态码
Error message
[%s] 请求返回状态码: %d
What it means
The ASH search endpoint responded, but with a status code other than 200. searchImpl treats any non-200 as a hard failure and reports the code so the caller can react. Body is already closed at this point, so only the status code is available.
Solutions
- Log the status code and retry later if 429/5xx; back off the request rate.
- Handle 403 by rotating headers/User-Agent, cookies, or using a proxy/residential IP.
- Verify the search URL path is still valid if you get 404 (site layout changed).
- Optionally treat the body of non-200 responses as diagnostic info before discarding it.
Example fix
// before
if resp.StatusCode != 200 {
return nil, fmt.Errorf("[%s] 请求返回状态码: %d", p.Name(), resp.StatusCode)
}
// after
if resp.StatusCode != 200 {
if resp.StatusCode == http.StatusTooManyRequests {
time.Sleep(retryAfterFrom(resp.Header))
}
io.Copy(io.Discard, io.LimitReader(resp.Body, 4096))
return nil, fmt.Errorf("[%s] 请求返回状态码: %d", p.Name(), resp.StatusCode)
} Defensive patterns
Strategy: retry
Validate before calling
// after response
if resp.StatusCode != 200 { return fmt.Errorf("upstream status %d", resp.StatusCode) } Try / catch
var statusErr *StatusError
if errors.As(err, &statusErr) {
switch {
case statusErr.Code == 429: backoffAndRetry()
case statusErr.Code >= 500: retryLater()
default: alertOnBlocked(statusErr.Code)
}
} Prevention
- Rate-limit requests to stay under upstream limits
- Rotate User-Agent/cookies if WAF-blocked
- Alert on recurring 403/429 to detect IP blocking
- Verify site path hasn't changed on 404s
When it happens
Trigger: After doRequestWithRetry succeeds, resp.StatusCode != 200 — e.g. 403 (blocked/Cloudflare), 429 (rate limited), 404 (path changed), 5xx (server error) — ash.go:99.
Common situations: Upstream added WAF/anti-bot protection returning 403; request rate too high causing 429; the site changed its search path causing 404; origin server 5xx during load.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/6cb1f526f5825405.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/ash/ash.go:99
// 创建请求
req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil)
if err != nil {
return nil, fmt.Errorf("[%s] 创建请求失败: %w", p.Name(), err)
}
// 设置请求头
p.setRequestHeaders(req)
// 发送请求(优化重试)
resp, err := p.doRequestWithRetry(req, client)
if err != nil {
return nil, fmt.Errorf("[%s] 搜索请求失败: %w", p.Name(), err)
}
defer resp.Body.Close()
// 检查状态码
if resp.StatusCode != 200 {
return nil, fmt.Errorf("[%s] 请求返回状态码: %d", p.Name(), resp.StatusCode)
}
// 读取响应(使用有限制的读取,避免读取过大内容)
// ASH页面通常不会太大,限制在2MB以内
limitReader := io.LimitReader(resp.Body, 2*1024*1024)
body, err := io.ReadAll(limitReader)
if err != nil {
return nil, fmt.Errorf("[%s] 读取响应失败: %w", p.Name(), err)
}
// 从HTML中提取JSON数据(直接传递字节,避免字符串转换)
results, err := p.extractResultsFromBytes(body)
if err != nil {
return nil, fmt.Errorf("[%s] 提取搜索结果失败: %w", p.Name(), err)
}
// 关键词过滤
filtered := plugin.FilterResultsByKeyword(results, keyword)View on GitHub (pinned to beaa561337)