{"record":{"id":"cdf012bf04e131be","repo":"fish2018/pansou","slug":"w-cdf012","errorCode":null,"errorMessage":"读取入口脚本失败: %w","messagePattern":"读取入口脚本失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/xiaokupan/xiaokupan.go","lineNumber":248,"sourceCode":"\treq.Header.Set(\"Accept\", \"text/html,application/xhtml+xml\")\n\thomeBody, err := doLimitedRequest(client, req, maxDiscoveryBodySize)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"读取首页失败: %w\", err)\n\t}\n\n\tassetPath := string(indexAssetPattern.Find(homeBody))\n\tif assetPath == \"\" {\n\t\treturn \"\", fmt.Errorf(\"首页未找到入口脚本\")\n\t}\n\tassetReq, err := http.NewRequestWithContext(ctx, http.MethodGet, strings.TrimRight(p.baseURL, \"/\")+assetPath, nil)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tassetReq.Header.Set(\"User-Agent\", req.Header.Get(\"User-Agent\"))\n\tassetReq.Header.Set(\"Referer\", homeURL)\n\tassetBody, err := doLimitedRequest(client, assetReq, maxDiscoveryBodySize)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"读取入口脚本失败: %w\", err)\n\t}\n\n\trouteIndex := strings.Index(string(assetBody), \"/s/$query\")\n\tif routeIndex < 0 {\n\t\treturn \"\", fmt.Errorf(\"入口脚本未找到搜索路由\")\n\t}\n\twindowStart := max(0, routeIndex-2048)\n\thashes := hashPattern.FindAll(assetBody[windowStart:routeIndex], -1)\n\tif len(hashes) == 0 {\n\t\treturn \"\", fmt.Errorf(\"入口脚本未找到搜索接口标识\")\n\t}\n\treturn string(hashes[len(hashes)-1]), nil\n}\n\nfunc parseSearchResponse(body []byte) ([]model.SearchResult, error) {\n\tvar root serovalNode\n\tif err := stdjson.Unmarshal(body, &root); err != nil {\n\t\treturn nil, fmt.Errorf(\"解析 Seroval 响应失败: %w\", err)","sourceCodeStart":230,"sourceCodeEnd":266,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/xiaokupan/xiaokupan.go#L230-L266","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"u, err := url.Parse(strings.TrimRight(p.baseURL, \"/\") + assetPath)\nif err != nil || u.Host == \"\" {\n\treturn fmt.Errorf(\"bad asset url: %v\", err)\n}","typeGuard":"func validAssetURL(base, path string) bool { u, err := url.Parse(base + path); return err == nil && u.Scheme != \"\" && u.Host != \"\" }","tryCatchPattern":"assetBody, err := doLimitedRequest(client, assetReq, maxDiscoveryBodySize)\nif err != nil {\n\treturn \"\", retry.Do(3, backoff, func() error { _, err := doLimitedRequest(client, assetReq.Clone(ctx), maxDiscoveryBodySize); return err })\n}","preventionTips":["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."],"tags":["network","http-request","scraping"],"backgroundTag":"http-request-failed","analyzedSha":"beaa56133755a548ebc51b090b3816e2ae044aa6","analyzedAt":"2026-09-07T00:31:18.025Z","contentChangedAt":"2026-09-07T00:31:18.025Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}