fish2018/pansou · error
读取入口脚本失败
Error message
读取入口脚本失败: %w
What it means
After extracting the entry-bundle path, discoverServerFunctionID issues a GET for the asset script via doLimitedRequest. Any transport-level failure (DNS, TLS, timeout, response body over maxDiscoveryBodySize, connection reset) is wrapped with this message and returned. It preserves the underlying cause via %w.
Solutions
- Print the final asset URL (baseURL + assetPath) and test it with curl to see whether the URL or the network is at fault.
- Increase request timeout / retry count in the HTTP client used by doLimitedRequest.
- If the body exceeds maxDiscoveryBodySize, raise that limit to the current bundle size.
- Verify the upstream site is up and not blocking your IP (check via a browser or different network).
Defensive patterns
Strategy: retry
Validate before calling
u, err := url.Parse(strings.TrimRight(p.baseURL, "/") + assetPath)
if err != nil || u.Host == "" {
return fmt.Errorf("bad asset url: %v", err)
} Type guard
func validAssetURL(base, path string) bool { u, err := url.Parse(base + path); return err == nil && u.Scheme != "" && u.Host != "" } Try / catch
assetBody, err := doLimitedRequest(client, assetReq, maxDiscoveryBodySize)
if err != nil {
return "", retry.Do(3, backoff, func() error { _, err := doLimitedRequest(client, assetReq.Clone(ctx), maxDiscoveryBodySize); return err })
} Prevention
- Set sane client timeouts and a small retry with backoff for asset fetches.
- Validate the assembled asset URL before requesting it.
- Keep maxDiscoveryBodySize comfortably above the real bundle size.
When it happens
Trigger: doLimitedRequest(client, assetReq, maxDiscoveryBodySize) returns a non-nil error while downloading the JS entry bundle referenced by the homepage — bad asset URL, network failure, timeout, or body-size limit exceeded.
Common situations: The extracted assetPath is relative and combined incorrectly with baseURL producing an invalid URL; site is unreachable/slow so the request times out; proxy or firewall blocks the asset host; the bundle grew past maxDiscoveryBodySize.
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/cdf012bf04e131be.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/xiaokupan/xiaokupan.go:248
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")
if routeIndex < 0 {
return "", fmt.Errorf("入口脚本未找到搜索路由")
}
windowStart := max(0, routeIndex-2048)
hashes := hashPattern.FindAll(assetBody[windowStart:routeIndex], -1)
if len(hashes) == 0 {
return "", fmt.Errorf("入口脚本未找到搜索接口标识")
}
return string(hashes[len(hashes)-1]), nil
}
func parseSearchResponse(body []byte) ([]model.SearchResult, error) {
var root serovalNode
if err := stdjson.Unmarshal(body, &root); err != nil {
return nil, fmt.Errorf("解析 Seroval 响应失败: %w", err)View on GitHub (pinned to beaa561337)