fish2018/pansou · error
[ ] 请求返回状态码
Error message
[%s] 请求返回状态码: %d
What it means
Status error in ikantv's doSearch (plugin/ikantv/ikantv.go:90): the search endpoint responded after retries with a non-200 status. The request and headers were accepted at transport level but the site refused the search (rate limit, block, or endpoint change).
Solutions
- Check the logged status code: 403/429 imply blocking or rate limiting — reduce request frequency or change IP; 404/5xx imply site changes or upstream outage.
- Verify the plugin's search URL/path still matches the current ikantv API and update it if the site changed.
- Ensure the User-Agent/Referer headers still pass the site's bot checks.
- Retry later if the status is 5xx — it is usually a transient upstream problem.
Example fix
// before
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("[%s] 请求返回状态码: %d", p.Name(), resp.StatusCode)
}
// after
if resp.StatusCode != http.StatusOK {
bodySnippet, _ := io.ReadAll(io.LimitReader(resp.Body, 500))
return nil, fmt.Errorf("[%s] 请求返回状态码: %d, body: %s", p.Name(), resp.StatusCode, string(bodySnippet))
} Defensive patterns
Strategy: retry
Validate before calling
// pre-flight: does the upstream still serve the search path?
resp, err := client.Head(searchURL)
if err == nil && (resp.StatusCode == 403 || resp.StatusCode == 429) {
return fmt.Errorf("ikantv is blocking this client (HTTP %d) — adjust rate/IP before searching", resp.StatusCode)
} Try / catch
results, err := p.doSearch(ctx, keyword)
if err != nil {
var statusErr *statusCodeError // if you wrap statuses in a typed error
if errors.As(err, &statusErr) {
switch {
case statusErr.Code == 429 || statusErr.Code == 403:
// back off / change IP / slow down
case statusErr.Code >= 500:
// transient: retry later
default:
// likely site change: check path/headers
}
}
} Prevention
- Respect rate limits to avoid 429/403 from anti-bot layers
- Keep User-Agent/Referer headers realistic and current
- Re-check the search path after any upstream site redesign
- Classify by status code: 5xx retry, 4xx fix request, 403/429 back off
When it happens
Trigger: resp.StatusCode != http.StatusOK: 403/429 from anti-bot or rate limiting, 404 because the search path changed, 5xx from upstream server errors.
Common situations: 默认 Referer 失效触发防盗链;服务端 5xx。
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/7f5cb4f8a0b0ab13.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/ikantv/ikantv.go:90
req, err := http.NewRequestWithContext(ctx, http.MethodGet, searchURL, nil)
if err != nil {
return nil, fmt.Errorf("[%s] 创建请求失败: %w", p.Name(), err)
}
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 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")
req.Header.Set("Connection", "keep-alive")
req.Header.Set("Referer", defaultReferer)
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 != http.StatusOK {
return nil, fmt.Errorf("[%s] 请求返回状态码: %d", p.Name(), resp.StatusCode)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("[%s] 读取响应失败: %w", p.Name(), err)
}
var apiResp apiResponse
if err := json.Unmarshal(body, &apiResp); err != nil {
return nil, fmt.Errorf("[%s] JSON解析失败: %w", p.Name(), err)
}
if apiResp.Code != 0 {
return nil, fmt.Errorf("[%s] API错误: %s", p.Name(), apiResp.Message)
}
results := convertResults(apiResp.Data)
return plugin.FilterResultsByKeyword(results, keyword), nil
}View on GitHub (pinned to beaa561337)