fish2018/pansou · error
[ ] 搜索请求失败
Error message
[%s] 搜索请求失败: %w
What it means
fetchSearch wraps any error from client.Do — the actual HTTP round trip for the search POST — as '[%s] 搜索请求失败'. client.Do returns an error for DNS resolution failure, TCP connect failure, TLS errors, and, critically, when the request's context deadline (requestTimeout) expires before the response completes. All transport-level problems surface here rather than as non-200 statuses.
Solutions
- Read the wrapped %w error: 'context deadline exceeded' means requestTimeout is too short or the site is slow — consider increasing requestTimeout.
- Verify DNS/connectivity to the site with curl from the same host (curl -v '<baseURL>') to rule out network/DNS/firewall issues.
- If a proxy is required on this machine, set HTTP(S)_PROXY or configure the http.Client's Transport with a ProxyFunc.
- Check for a redirect to a new domain (site moved) and update baseURL; add a retry with backoff for transient connection resets.
Example fix
// before
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("[%s] 搜索请求失败: %w", p.Name(), err)
}
// after
resp, err := client.Do(req)
if err != nil {
if errors.Is(err, context.DeadlineExceeded) {
return nil, fmt.Errorf("[%s] 搜索请求超时(>%s), 可尝试增大 requestTimeout: %w", p.Name(), requestTimeout, err)
}
return nil, fmt.Errorf("[%s] 搜索请求失败: %w", p.Name(), err)
} Defensive patterns
Strategy: retry
Validate before calling
// 网络连通性预检(可选)
if _, err := net.LookupHost("5266ys-site-domain"); err != nil {
return nil, fmt.Errorf("DNS解析失败: %w", err)
} Try / catch
result, err := p.Search(ctx, keyword)
if err != nil {
if errors.Is(err, context.DeadlineExceeded) {
// 增大超时后重试
} else if isTransientNetErr(err) {
// 指数退避重试 2-3 次
} else {
return err
}
} Prevention
- Set requestTimeout generously (10-30s) for slow scraping targets.
- Configure proxy settings on the http.Client Transport when required by the network.
- Add exponential backoff retries for transient network errors.
- Check DNS/connectivity to the target site before bulk searches.
When it happens
Trigger: client.Do(req) returns err inside fetchSearch: DNS failure for the site domain, connection refused/reset/timeout, TLS handshake failure, context deadline exceeded from context.WithTimeout(requestTimeout), or a proxy misconfiguration in the default transport.
Common situations: The target site is blocked or geo-restricted on the host machine; a corporate firewall/proxy drops the POST; the site is slow and requestTimeout (a few seconds) is too short; the site domain changed and DNS no longer resolves.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/dcb8d69e4de05412.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/5266ys/5266ys.go:182
}
func (p *Plugin) fetchSearch(client *http.Client, keyword string) (*goquery.Document, error) {
encoded, err := encodeGB18030(keyword)
if err != nil {
return nil, fmt.Errorf("[%s] 编码搜索关键词失败: %w", p.Name(), err)
}
form := "show=title%2Csmalltext&tempid=1&tbname=article&keyboard=" + url.QueryEscape(string(encoded)) + "&submit="
ctx, cancel := context.WithTimeout(context.Background(), requestTimeout)
defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodPost, baseURL+searchPath, strings.NewReader(form))
if err != nil {
return nil, fmt.Errorf("[%s] 创建搜索请求失败: %w", p.Name(), err)
}
setHeaders(req, baseURL+"/")
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
resp, err := client.Do(req)
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] 搜索请求返回 HTTP %d", p.Name(), resp.StatusCode)
}
body, err := io.ReadAll(io.LimitReader(resp.Body, 4<<20))
if err != nil {
return nil, fmt.Errorf("[%s] 读取搜索结果失败: %w", p.Name(), err)
}
decoded, err := decodeGB18030(body)
if err != nil {
return nil, fmt.Errorf("[%s] 解码搜索结果失败: %w", p.Name(), err)
}
doc, err := goquery.NewDocumentFromReader(strings.NewReader(decoded))
if err != nil {
return nil, fmt.Errorf("[%s] 解析搜索结果失败: %w", p.Name(), err)
}
return doc, nilView on GitHub (pinned to beaa561337)