fish2018/pansou · error

[ ] 获取搜索结果失败

Error message

[%s] 获取搜索结果失败: %w

What it means

xdpan's searchImpl wraps any error from fetchSearchResults with the plugin name prefix: '[xdpan] 获取搜索结果失败: %w'. It is a top-level aggregation point — the root cause is one of the wrapped errors inside fetchSearchResults (request creation, transport failure, non-200 status, Cloudflare challenge, or HTML parse failure).

Solutions

  1. Unwrap the chained error (%w) to find the root cause and fix that specific failure first.
  2. If the root cause is the Cloudflare challenge, wait, change network/IP, or update cookies before retrying.
  3. Check the configured baseURL is reachable (curl the /search?page=1&k=... endpoint directly).
  4. Retry with backoff for transient network/5xx root causes.
Defensive patterns

Strategy: try-catch

Try / catch

results, err := pluginSearch(keyword)
if err != nil {
	// unwrap the chain to reach the root cause
	root := err
	for errors.Unwrap(root) != nil { root = errors.Unwrap(root) }
	log.Printf("xdpan search root cause: %v", root)
}

Prevention

When it happens

Trigger: Any failure in fetchSearchResults during a xdpan search: malformed search URL, network/DNS/timeout on the GET, non-200 response, 'Just a moment...' Cloudflare challenge page, or goquery parse error. searchImpl then re-wraps with the plugin name.

Common situations: The xdpan site is behind Cloudflare and serving browser verification to datacenter IPs; the site is down or moved; keyword contains characters that break the query string; rate limiting after frequent searches.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07). Data as JSON: /api/errors/8e49be5a7a6ece53. Report an issue: GitHub.

Appendix: source

Thrown at plugin/xdpan/xdpan.go:74

// SearchWithResult 执行搜索并返回包含IsFinal标记的结果
func (p *XdpanPlugin) SearchWithResult(keyword string, ext map[string]interface{}) (model.PluginSearchResult, error) {
	return p.AsyncSearchWithResult(keyword, p.searchImpl, p.MainCacheKey, ext)
}

// searchImpl 实现搜索逻辑
func (p *XdpanPlugin) searchImpl(client *http.Client, keyword string, ext map[string]interface{}) ([]model.SearchResult, error) {
	if DebugLog {
		fmt.Printf("[xdpan] 开始搜索: keyword=%s\n", keyword)
	}

	// Step 1: 获取搜索结果页面
	searchResults, err := p.fetchSearchResults(client, keyword)
	if err != nil {
		if DebugLog {
			fmt.Printf("[xdpan] 获取搜索结果失败: %v\n", err)
		}
		return nil, fmt.Errorf("[%s] 获取搜索结果失败: %w", p.Name(), err)
	}
	if DebugLog {
		fmt.Printf("[xdpan] 获取搜索结果成功: 结果数=%d\n", len(searchResults))
	}

	// Step 2: 并发获取详情页信息(获取真实的百度网盘链接)
	p.enrichWithDetailInfo(client, searchResults)
	searchResults = filterResultsWithLinks(searchResults)

	// Step 3: 关键词过滤
	filteredResults := plugin.FilterResultsByKeyword(searchResults, keyword)
	if DebugLog {
		fmt.Printf("[xdpan] 关键词过滤后: 过滤前=%d, 过滤后=%d\n", len(searchResults), len(filteredResults))
	}

	return filteredResults, nil
}

View on GitHub (pinned to beaa561337)