fish2018/pansou · error
HTTP
Error message
HTTP %d
What it means
fetchDetail throws this generic status-code error when the detail endpoint returns any non-200, non-403 HTTP status (e.g. 404, 429, 500, 502). It signals an unexpected server-side or routing failure rather than a session problem; the plugin deliberately does not parse the body in this branch.
Solutions
- Check DebugLog output for the printed status code to identify the class of failure.
- Retry with backoff for transient 429/5xx statuses.
- If 404, refresh search results to obtain a valid resource ID/type.
- Check the site's availability in a browser; if down, wait and retry later.
Example fix
// before
body, statusCode, _, err := p.requestWithChallengeRetry(scraper, http.MethodGet, detailURL, "", "")
// after
body, statusCode, _, err := p.requestWithChallengeRetry(scraper, http.MethodGet, detailURL, "", "")
if err == nil && statusCode == http.StatusTooManyRequests {
time.Sleep(retryBackoff)
body, statusCode, _, err = p.requestWithChallengeRetry(scraper, http.MethodGet, detailURL, "", "")
} Defensive patterns
Strategy: retry
Validate before calling
// preflight availability check
resp, err := http.Head(siteBaseURL)
if err != nil || resp.StatusCode >= 500 { return errors.New("site unavailable") } Type guard
func isRetryableStatus(err error) bool {
if err == nil { return false }
var code int
if _, e := fmt.Sscanf(err.Error(), "HTTP %d", &code); e != nil { return false }
return code == 429 || code >= 500
} Try / catch
detail, err := plugin.fetchDetail(id, typ, scraper)
if isRetryableStatus(err) {
time.Sleep(5 * time.Second)
detail, err = plugin.fetchDetail(id, typ, scraper)
} Prevention
- Implement exponential backoff for 429 and 5xx statuses.
- Check site availability/maintenance before large batch runs.
- Refresh search results instead of reusing old resource IDs.
- Cap concurrency so the site does not throttle you.
When it happens
Trigger: Calling fetchDetail while the site returns a status other than 200/403: resource deleted (404), rate limiting (429), upstream maintenance (5xx), or redirects followed to an error page.
Common situations: Site under maintenance or temporarily down; too many concurrent detail fetches triggering 429; resource ID/type from stale search results that no longer exist; CDN misbehaving.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/23febc88cfdf1dc9.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/gying/gying.go:2725
}
if DebugLog {
fmt.Printf("[Gying] 响应状态码: %d\n", statusCode)
}
// 检查403错误
if statusCode == http.StatusForbidden {
if DebugLog {
fmt.Printf("[Gying] ❌ 详情接口返回403 - Cookie可能已过期\n")
}
return nil, fmt.Errorf("HTTP 403 Forbidden")
}
if statusCode != http.StatusOK {
if DebugLog {
fmt.Printf("[Gying] ❌ HTTP错误: %d\n", statusCode)
}
return nil, fmt.Errorf("HTTP %d", statusCode)
}
if DebugLog {
fmt.Printf("[Gying] 响应长度: %d 字节\n", len(body))
}
if isLoginShell(body) {
return nil, fmt.Errorf("HTTP 403 Forbidden")
}
var detail DetailData
if err := json.Unmarshal(body, &detail); err != nil {
if DebugLog {
fmt.Printf("[Gying] JSON解析失败: %v\n", err)
// 打印前200字符
preview := string(body)
if len(preview) > 200 {
preview = preview[:200] + "..."
}View on GitHub (pinned to beaa561337)