fish2018/pansou · error
[ ] 搜索失败: ;刷新接口标识失败
Error message
[%s] 搜索失败: %v;刷新接口标识失败: %w
What it means
This error is returned by XiaokupanPlugin.searchImpl when the initial search against xiaokupan.com's TanStack server function endpoint fails AND the automatic recovery path (re-discovering the server function ID from the site's homepage and entry JS bundle) also fails. It wraps the original search error (%v) and the refresh error (%w) so both root causes are visible in one message.
Solutions
- Check network connectivity/DNS to xiaokupan.com (curl https://xiaokupan.com/) — most often both errors share the same network root cause
- Inspect the wrapped refresh error to see whether discovery failed at homepage fetch, asset lookup, or hash extraction
- If the site redeployed, verify the /assets/index-*.js regex and hash extraction logic in discoverServerFunctionID still match the live bundle
- Retry after a short delay; if the site is under maintenance the error is transient
- Update defaultServerFunctionID to the hash currently embedded in the site's entry JS as a stopgap
Example fix
// before: opaque chained failure
return nil, fmt.Errorf("[%s] 搜索失败: %v;刷新接口标识失败: %w", p.Name(), err, refreshErr)
// after: surface both causes explicitly and retry once before giving up
if refreshErr != nil {
return nil, fmt.Errorf("xiaokupan: search failed: %v; function-id refresh failed: %w", err, refreshErr)
} Defensive patterns
Strategy: fallback
Validate before calling
func canReachXiaokupan() error {
resp, err := http.Head("https://xiaokupan.com/")
if err != nil { return err }
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK { return fmt.Errorf("homepage HTTP %d", resp.StatusCode) }
return nil
} Try / catch
results, err := plugin.SearchWithResult(keyword, ext)
if err != nil {
var wrapped interface{ Unwrap() error }
log.Printf("xiaokupan search and function-id refresh both failed: %v", err) // inspect %v part for original cause
return fallbackOtherPlugins(keyword)
} Prevention
- Monitor reachability of xiaokupan.com with a periodic health check
- Pin and periodically re-verify defaultServerFunctionID against the live site bundle
- Alert on this dual-failure message since it means both primary and recovery paths are broken
When it happens
Trigger: searchWithFunctionID returns an error for the cached functionID (network failure, HTTP non-200, stale/discontinued function ID hash, oversized response, parse failure), and then refreshServerFunctionID -> discoverServerFunctionID also errors (homepage unreachable, entry script pattern no longer matches, hash not found, or the same network/HTTP problems).
Common situations: xiaokupan.com redeployed its frontend so the baked-in defaultServerFunctionID (sha hash) is stale; the site is down or behind a firewall/proxy; the HTML layout changed so the regex /assets/index-*.js no longer matches; transient DNS/timeouts affecting both requests.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/fc4b64c8286b2faf.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/xiaokupan/xiaokupan.go:99
func (p *XiaokupanPlugin) SearchWithResult(keyword string, ext map[string]interface{}) (model.PluginSearchResult, error) {
return p.AsyncSearchWithResult(keyword, p.searchImpl, p.MainCacheKey, ext)
}
func (p *XiaokupanPlugin) searchImpl(client *http.Client, keyword string, _ map[string]interface{}) ([]model.SearchResult, error) {
keyword = cleanText(keyword)
if keyword == "" {
return []model.SearchResult{}, nil
}
if client == nil {
client = http.DefaultClient
}
functionID := p.currentServerFunctionID()
results, err := p.searchWithFunctionID(client, keyword, functionID)
if err != nil {
refreshedID, refreshErr := p.refreshServerFunctionID(client, functionID)
if refreshErr != nil {
return nil, fmt.Errorf("[%s] 搜索失败: %v;刷新接口标识失败: %w", p.Name(), err, refreshErr)
}
results, err = p.searchWithFunctionID(client, keyword, refreshedID)
}
if err != nil {
return nil, fmt.Errorf("[%s] 搜索失败: %w", p.Name(), err)
}
return plugin.FilterResultsByKeyword(results, keyword), nil
}
func (p *XiaokupanPlugin) searchWithFunctionID(client *http.Client, keyword, functionID string) ([]model.SearchResult, error) {
payload, err := buildSearchPayload(keyword)
if err != nil {
return nil, fmt.Errorf("构造搜索参数失败: %w", err)
}
endpoint := fmt.Sprintf("%s/_serverFn/%s", strings.TrimRight(p.baseURL, "/"), functionID)
parsedEndpoint, err := url.Parse(endpoint)
if err != nil {View on GitHub (pinned to beaa561337)