fish2018/pansou · error
发送搜索请求失败
Error message
发送搜索请求失败: %w
What it means
searchImpl in the libvio plugin wraps errors from p.doRequest (the HTTP GET to the search URL) with this message. The request failed before any response was available; the underlying transport error is chained via %w.
Solutions
- Inspect the wrapped cause from %w for the transport-level reason
- Verify the site is reachable with curl from the same host; update BaseURL if the domain moved
- Increase the HTTP client timeout and add retry with backoff
- Adjust headers (User-Agent, Referer) or use a proxy if the site blocks automated traffic
- Check for TLS interception issues and enable InsecureSkipVerify only for diagnostics
Defensive patterns
Strategy: try-catch
Validate before calling
u, err := url.Parse(searchURL)
if err != nil || u.Host == "" {
return fmt.Errorf("invalid libvio search URL: %q", searchURL)
} Try / catch
results, err := plugin.Search(ctx, keyword)
if err != nil {
if strings.Contains(err.Error(), "发送搜索请求失败") {
cause := errors.Unwrap(err)
log.Printf("libvio transport failure: %v", cause)
return fallbackSearch(keyword)
}
return err
} Prevention
- Health-check the libvio domain and update BaseURL on domain changes
- Use a browser-like User-Agent/Referer to reduce bot blocking
- Add retry with backoff for transient transport errors
- Verify TLS works with Go's client (some sites block non-browser TLS fingerprints)
- Log errors.Unwrap(err) so the root transport cause is visible
When it happens
Trigger: p.doRequest(client, searchURL, BaseURL) returns a non-nil error during a keyword search: connection refused/reset, DNS failure, TLS error, timeout, or proxy failure.
Common situations: libvio site is down or blocks datacenter IPs; TLS fingerprint blocking of Go's default client; DNS failure in containerized deployments; client timeout too short; site domain changed.
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/11d4c612ceefae63.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/libvio/libvio.go:135
log.Printf("[Libvio] 响应状态: %d", resp.StatusCode)
}
return resp, nil
}
// searchImpl 实际的搜索实现
func (p *LibvioPlugin) searchImpl(client *http.Client, keyword string, ext map[string]interface{}) ([]model.SearchResult, error) {
searchURL := fmt.Sprintf("%s%s?wd=%s&submit=", BaseURL, SearchPath, url.QueryEscape(keyword))
if p.debugMode {
log.Printf("[Libvio] 开始搜索: %s", keyword)
log.Printf("[Libvio] 搜索URL: %s", searchURL)
}
// 发送搜索请求
resp, err := p.doRequest(client, searchURL, BaseURL)
if err != nil {
return nil, fmt.Errorf("发送搜索请求失败: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("搜索响应状态码异常: %d", resp.StatusCode)
}
// 处理响应体(可能是gzip压缩的)
reader, err := p.getResponseReader(resp)
if err != nil {
return nil, err
}
// 解析HTML
doc, err := goquery.NewDocumentFromReader(reader)
if err != nil {
return nil, fmt.Errorf("解析HTML失败: %w", err)
}View on GitHub (pinned to beaa561337)