fish2018/pansou · error
读取首页失败
Error message
读取首页失败: %w
What it means
Wraps any error from doLimitedRequest while fetching the xiaokupan homepage (https://xiaokupan.com/) inside discoverServerFunctionID. Discovery is the fallback path used when the cached server-function ID fails, so this error means the recovery step itself could not even download the homepage HTML needed to locate the entry JS asset.
Solutions
- Check the wrapped cause: 请求失败 → connectivity, HTTP 403 → anti-bot, HTTP 5xx → site down, timeout → slow site
- Verify with curl -v https://xiaokupan.com/ that the homepage is reachable from the host
- For 403, update request headers (User-Agent/Accept already set) or resolve IP blocking with the site
- Note the cached functionID remains in use until discovery succeeds — fix connectivity so future refreshes can run
- Retry later if the site is under maintenance
Defensive patterns
Strategy: fallback
Validate before calling
resp, err := http.Head("https://xiaokupan.com/")
if err != nil || resp.StatusCode != http.StatusOK {
return errors.New("xiaokupan homepage unreachable; discovery will fail")
}
resp.Body.Close() Try / catch
if strings.Contains(err.Error(), "读取首页失败") {
// recovery path failed at the very first step; keep cached functionID
// and fall back to other search sources
return fallbackSearch(keyword)
} Prevention
- Health-check the homepage before relying on this plugin
- Keep the cached defaultServerFunctionID valid so discovery is rarely needed
- Ensure stable egress and browser-like headers to survive the site's WAF
When it happens
Trigger: Homepage fetch fails via doLimitedRequest: network error (请求失败 wrapper), non-200 status (HTTP NNN wrapper), mid-body read failure, or homepage body exceeding maxDiscoveryBodySize (8MiB). Triggered when searchImpl detects a stale/broken function ID and calls refreshServerFunctionID -> discoverServerFunctionID.
Common situations: Site down or DNS unreachable at the moment of recovery; Cloudflare/WAF blocking the programmatic homepage request (403); homepage served a 5xx during maintenance; very slow homepage load hitting the 30s timeout.
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/1e552f30d0c94e3f.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/xiaokupan/xiaokupan.go:233
}
p.serverFunctionID = discoveredID
return discoveredID, nil
}
func (p *XiaokupanPlugin) discoverServerFunctionID(client *http.Client) (string, error) {
ctx, cancel := context.WithTimeout(context.Background(), requestTimeout)
defer cancel()
homeURL := strings.TrimRight(p.baseURL, "/") + "/"
req, err := http.NewRequestWithContext(ctx, http.MethodGet, homeURL, nil)
if err != nil {
return "", err
}
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36")
req.Header.Set("Accept", "text/html,application/xhtml+xml")
homeBody, err := doLimitedRequest(client, req, maxDiscoveryBodySize)
if err != nil {
return "", fmt.Errorf("读取首页失败: %w", err)
}
assetPath := string(indexAssetPattern.Find(homeBody))
if assetPath == "" {
return "", fmt.Errorf("首页未找到入口脚本")
}
assetReq, err := http.NewRequestWithContext(ctx, http.MethodGet, strings.TrimRight(p.baseURL, "/")+assetPath, nil)
if err != nil {
return "", err
}
assetReq.Header.Set("User-Agent", req.Header.Get("User-Agent"))
assetReq.Header.Set("Referer", homeURL)
assetBody, err := doLimitedRequest(client, assetReq, maxDiscoveryBodySize)
if err != nil {
return "", fmt.Errorf("读取入口脚本失败: %w", err)
}
routeIndex := strings.Index(string(assetBody), "/s/$query")View on GitHub (pinned to beaa561337)