fish2018/pansou · error
[ ] 搜索请求失败
Error message
[%s] 搜索请求失败: %w
What it means
searchImpl wraps a doRequestWithRetry failure as "[%s] 搜索请求失败". It means the search request to daishuduanju.com failed at the transport layer or exhausted all retries — the response was never obtained.
Solutions
- Check the wrapped cause for context.DeadlineExceeded; if so, increase searchTimeout.
- Verify the site is reachable from your network (curl -I https://www.daishuduanju.com).
- Retry later if the site is temporarily down or rate-limiting your IP.
- Increase maxRetries/backoff in doRequestWithRetry for flaky connections.
Defensive patterns
Strategy: retry
Try / catch
results, err := plugin.Search(ctx, keyword)
if err != nil {
if errors.Is(err, context.DeadlineExceeded) {
// searchTimeout too short — retry with a larger timeout
}
return nil, fmt.Errorf("search unavailable: %w", err)
} Prevention
- Set searchTimeout comfortably above expected network latency.
- Verify the site is reachable from your region/network.
- Use backoff between retries; avoid hammering a downed site.
When it happens
Trigger: Calling the plugin search when the GET https://www.daishuduanju.com/?s=<keyword> fails in every attempt: timeout (searchTimeout context expired), DNS failure, TLS error, or connection refused/reset.
Common situations: Site is down or blocked in the user's region/ISP, anti-bot TLS fingerprinting resets connections, searchTimeout is too short for a slow network, or DNS poisoning of the domain.
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/b24637dac65f6ee8.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/daishudj/daishudj.go:137
func (p *DaishuPlugin) searchImpl(client *http.Client, keyword string, ext map[string]interface{}) ([]model.SearchResult, error) {
if p.client != nil {
client = p.client
}
searchURL := fmt.Sprintf("https://www.daishuduanju.com/?s=%s", url.QueryEscape(keyword))
ctx, cancel := context.WithTimeout(context.Background(), searchTimeout)
defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, searchURL, nil)
if err != nil {
return nil, fmt.Errorf("[%s] 创建搜索请求失败: %w", p.Name(), err)
}
setCommonHeaders(req, "https://www.daishuduanju.com/")
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 != http.StatusOK {
return nil, fmt.Errorf("[%s] 搜索返回状态码: %d", p.Name(), resp.StatusCode)
}
doc, err := goquery.NewDocumentFromReader(resp.Body)
if err != nil {
return nil, fmt.Errorf("[%s] 解析搜索页面失败: %w", p.Name(), err)
}
var (
results []model.SearchResult
wg sync.WaitGroup
mu sync.Mutex
sem = make(chan struct{}, maxConcurrency)
)View on GitHub (pinned to beaa561337)