fish2018/pansou · error
unknown request error
Error message
unknown request error
What it means
This is a fallback sentinel inside QiweiPlugin.doRequestWithRetry (plugin/qiwei/qiwei.go:659). After 3 attempts the loop reports the last transport/status error; if lastErr is somehow nil (e.g. the server consistently returned a non-200 status so no err was recorded), this 'unknown request error' is used as the wrapped cause. It signals the request failed for a non-obvious reason — most often repeated non-200 HTTP responses.
Solutions
- Log resp.StatusCode on each retry attempt to see which non-200 status is actually occurring
- Check network/proxy connectivity to the qiwei endpoint (curl -v the URL)
- Retry later with backoff — the plugin already retries 3 times with exponential backoff, so persistent failure means the endpoint is down or blocking
- If caused by anti-bot blocking, refresh cookies/verification state before calling again
Example fix
// before
if lastErr == nil {
lastErr = fmt.Errorf("unknown request error")
}
// after
if lastErr == nil {
lastErr = fmt.Errorf("non-200 status after retries")
} Defensive patterns
Strategy: retry
Validate before calling
// caller-side: prefer checking status explicitly if you control the client
req, _ := http.NewRequestWithContext(ctx, "GET", qiweiURL, nil)
if req == nil || qiweiURL == "" {
return errors.New("qiwei request not initialized")
} Type guard
if resp != nil && resp.StatusCode == http.StatusOK {
// safe to use resp
} Try / catch
resp, err := p.doRequestWithRetry(req, client)
if err != nil {
if strings.Contains(err.Error(), "unknown request error") {
// non-200 after all retries; inspect upstream status/health
}
return err
} Prevention
- Monitor the qiwei endpoint's health/status codes
- Refresh session cookies before long-running request loops
- Set realistic client timeouts matching the retry backoff window
- Log resp.StatusCode per attempt to make non-200 failures diagnosable
When it happens
Trigger: solveVerification or fetchBody calls doRequestWithRetry; all 3 attempts get an HTTP response with StatusCode != 200, so client.Do returns no error and lastErr stays nil when the fallback is built.
Common situations: WeCom (qiwei) endpoint temporarily returning 4xx/5xx (rate limiting, maintenance, blocked UA), a proxy/gateway returning 502/503 repeatedly, or the target page redirecting to an anti-bot challenge page with a non-200 code.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/32ae0c9ac1438b37.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/qiwei/qiwei.go:659
var lastErr error
for i := 0; i < maxRetries; i++ {
if i > 0 {
time.Sleep(time.Duration(1<<uint(i-1)) * 200 * time.Millisecond)
}
resp, err := client.Do(req.Clone(req.Context()))
if err == nil && resp != nil && resp.StatusCode == http.StatusOK {
return resp, nil
}
if resp != nil {
resp.Body.Close()
}
lastErr = err
}
if lastErr == nil {
lastErr = fmt.Errorf("unknown request error")
}
return nil, fmt.Errorf("[%s] 重试 %d 次后仍失败: %w", p.Name(), maxRetries, lastErr)
}
func (p *QiweiPlugin) setHeaders(req *http.Request, referer string) {
req.Header.Set("User-Agent", userAgent)
req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,application/json;q=0.8,*/*;q=0.7")
req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8")
req.Header.Set("Connection", "keep-alive")
req.Header.Set("Upgrade-Insecure-Requests", "1")
if referer != "" {
req.Header.Set("Referer", referer)
}
}
func (p *QiweiPlugin) hostCandidates() []string {
p.hostMu.RLock()
active := p.activeHostView on GitHub (pinned to beaa561337)