fish2018/pansou · error
[ ] 请求返回状态码
Error message
[%s] 请求返回状态码: %d
What it means
The NSGame search API returned an HTTP status code other than 200; the plugin treats any non-200 as a hard failure and surfaces the raw code. This happens after the request itself succeeded (no transport error), meaning the server actively responded with an error or redirect/anti-bot page status.
Solutions
- Log resp.Status and a body snippet on non-200 to identify the actual blocker (WAF page vs 5xx)
- Reduce request frequency / add jittered backoff if 429
- Check whether nsthwj.cn changed its API path and update apiURL
- Send the session headers/cookies produced by ensureSession (setRequestHeaders with Referer https://nsthwj.cn/) exactly as a browser would to pass WAF checks
- Retry later if it's a 5xx outage
Example fix
// before
if resp.StatusCode != 200 {
return nil, fmt.Errorf("[%s] 请求返回状态码: %d", p.Name(), resp.StatusCode)
}
// after
if resp.StatusCode != 200 {
snippet, _ := io.ReadAll(io.LimitReader(resp.Body, 256))
return nil, fmt.Errorf("[%s] 请求返回状态码: %d, body: %s", p.Name(), resp.StatusCode, snippet)
} Defensive patterns
Strategy: retry
Validate before calling
// preemptive check of upstream health
resp, err := http.Get("https://nsthwj.cn/")
if err == nil && resp.StatusCode == http.StatusForbidden {
log.Warn("upstream WAF is blocking this IP")
}
if resp != nil { resp.Body.Close() } Try / catch
results, err := plugin.Search(keyword, ext)
var statusErr *plugin.StatusError
if errors.As(err, &statusErr) && statusErr.Code == 429 {
time.Sleep(backoff)
// retry once
} Prevention
- Throttle request rate to avoid 429 rate limiting
- Log response status and a body snippet to detect WAF/Cloudflare pages early
- Keep browser-like headers (User-Agent, Referer) current
- Alert on sustained non-200 rates so site changes are noticed
When it happens
Trigger: Server responds 403/429/503 from anti-bot or rate limiting, 5xx from upstream outage, 404 when the apiURL path changed, or 302/301 if the client follows redirects to an HTML page with an error status.
Common situations: The site deployed Cloudflare/WAF challenge returning 403, scraping too aggressively triggering 429, site maintenance returning 502/503, or the plugin's hardcoded apiURL changed after a site update.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/b36072dc5fc8cd15.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/nsgame/nsgame.go:167
if err != nil {
return nil, fmt.Errorf("[%s] 创建请求失败: %w", p.Name(), err)
}
// 4. 设置请求头
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36")
req.Header.Set("Accept", "application/json, text/plain, */*")
req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8")
p.setRequestHeaders(req, "https://nsthwj.cn/")
// 5. 发送请求(带重试机制)
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)
}
// 6. 读取响应体
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("[%s] 读取响应失败: %w", p.Name(), err)
}
// 7. 解析JSON响应
var apiResp NSGameResponse
if err := json.Unmarshal(body, &apiResp); err != nil {
return nil, fmt.Errorf("[%s] JSON解析失败: %w", p.Name(), err)
}
// 8. 检查响应状态
if !apiResp.Success || (apiResp.Code != "" && apiResp.Code != "200") {
return nil, fmt.Errorf("[%s] API返回错误: success=%v, code=%s", p.Name(), apiResp.Success, apiResp.Code)
}View on GitHub (pinned to beaa561337)