fish2018/pansou · error
[ ] 搜索请求失败
Error message
[%s] 搜索请求失败: %w
What it means
The retry-wrapped search HTTP request (p.doRequestWithRetry) ultimately failed after exhausting its retries. The transport error is wrapped with the plugin name and returned, aborting the pianku search.
Solutions
- Check connectivity to pianku from the host (curl the search URL)
- Inspect the wrapped %w cause to distinguish DNS vs timeout vs connection reset
- Increase retry count/timeout in doRequestWithRetry if failures are intermittent
- Add a proxy or alternate endpoint if the site blocks the server's IP range
Example fix
// before
resp, err := p.doRequestWithRetry(req, client)
if err != nil {
return nil, fmt.Errorf("[%s] 搜索请求失败: %w", p.Name(), err)
}
// after
resp, err := p.doRequestWithRetry(req, client)
if err != nil {
if ne, ok := err.(net.Error); ok && ne.Timeout() {
return nil, fmt.Errorf("[%s] 搜索请求超时(已重试): %w", p.Name(), err)
}
return nil, fmt.Errorf("[%s] 搜索请求失败: %w", p.Name(), err)
} Defensive patterns
Strategy: retry
Validate before calling
conn, err := net.DialTimeout("tcp", "www.pianku.cc:443", 5*time.Second)
if err != nil { /* upstream unreachable */ } else { conn.Close() } Try / catch
results, err := plugin.Search(keyword, ext)
if err != nil {
var urlErr *url.Error
if errors.As(err, &urlErr) && urlErr.Timeout() {
// retry with longer timeout / backoff
} else {
// network-level failure: fail over to other plugins
}
} Prevention
- Use exponential backoff on transport errors
- Monitor DNS and egress connectivity in the deployment environment
- Set sane client timeouts so retries have a chance to succeed
When it happens
Trigger: All retry attempts of the GET to pianku's search page failed — persistent DNS failure, connection refused/reset, TLS errors, or request timeout against the configured HTTP client.
Common situations: Site unreachable from the server's network/region; pianku blocking datacenter IPs; DNS misconfiguration in the container; timeout too short for retries to help.
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/5d27ae738199efad.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/pianku/pianku.go:141
searchURL := fmt.Sprintf("%s%s?wd=%s", BaseURL, SearchPath, url.QueryEscape(searchKeyword))
// 创建带超时的上下文
ctx, cancel := context.WithTimeout(context.Background(), TimeoutSeconds*time.Second)
defer cancel()
// 创建请求
req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil)
if err != nil {
return nil, fmt.Errorf("[%s] 创建请求失败: %w", p.Name(), err)
}
// 设置请求头
p.setRequestHeaders(req)
// 发送HTTP请求(带重试机制)
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 != 200 {
return nil, fmt.Errorf("[%s] 请求返回状态码: %d", p.Name(), resp.StatusCode)
}
// 解析HTML
doc, err := goquery.NewDocumentFromReader(resp.Body)
if err != nil {
return nil, fmt.Errorf("[%s] HTML解析失败: %w", p.Name(), err)
}
// 提取搜索结果基本信息
searchResults := p.extractSearchResults(doc)
// 为每个搜索结果获取详情页的下载链接View on GitHub (pinned to beaa561337)