{"record":{"id":"b3870bf87e6e19e7","repo":"fish2018/pansou","slug":"get-w-b3870b","errorCode":null,"errorMessage":"GET请求失败: %w","messagePattern":"GET请求失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/xdpan/xdpan.go","lineNumber":114,"sourceCode":"\tsearchURL := fmt.Sprintf(\"%s/search?page=1&k=%s&p=baidu\", strings.TrimRight(p.baseURL, \"/\"), url.QueryEscape(keyword))\n\n\tctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)\n\tdefer cancel()\n\n\treq, err := http.NewRequestWithContext(ctx, \"GET\", searchURL, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"创建GET请求失败: %w\", err)\n\t}\n\n\tp.setRequestHeaders(req)\n\n\tif DebugLog {\n\t\tfmt.Printf(\"[xdpan] 搜索URL: %s\\n\", searchURL)\n\t}\n\n\tresp, err := p.doRequestWithRetry(req, client)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"GET请求失败: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"请求返回状态码: %d\", resp.StatusCode)\n\t}\n\n\t// 解析HTML\n\tdoc, err := goquery.NewDocumentFromReader(io.LimitReader(resp.Body, maxPageSize))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"解析HTML失败: %w\", err)\n\t}\n\n\tresults := p.extractSearchResults(doc)\n\tif len(results) == 0 && doc.Find(\"title\").First().Text() == \"Just a moment...\" {\n\t\treturn nil, fmt.Errorf(\"站点触发 Cloudflare 浏览器验证\")\n\t}\n\treturn results, nil","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/xdpan/xdpan.go#L96-L132","documentation":"xdpan's fetchSearchResults executes the search GET via doRequestWithRetry and wraps any transport error as 'GET请求失败: %w'. doRequestWithRetry already handles retries, so this error means the request exhausted retries and still failed — a persistent network, DNS, TLS, or timeout problem reaching the xdpan search endpoint.","triggerScenarios":"p.doRequestWithRetry returns an error after all retries: connection refused, DNS failure, TLS handshake error, context deadline exceeded (30s timeout), or connection reset while requesting baseURL/search?page=1&k=<keyword>&p=baidu.","commonSituations":"Site is down or blocked from the user's network/region; DNS pollution of the domain; corporate firewall blocks outbound requests; the 30-second timeout expires on a slow/unresponsive server; Cloudflare dropping non-browser TLS fingerprints.","solutions":["Test connectivity to the site directly (curl -v the searchURL) to distinguish local network issues from site outages.","Check DNS resolution and try an alternate resolver or mirror domain if the domain is polluted/unreachable.","Verify proxy/VPN settings if the site is region-blocked from your network.","If timeouts persist, check site latency and increase the 30s context timeout or reduce concurrency."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if err := probeReachable(baseURL, 5*time.Second); err != nil { /* skip plugin, site unreachable */ }","typeGuard":null,"tryCatchPattern":"results, err := pluginSearch(keyword)\nif err != nil {\n\tif errors.Is(err, context.DeadlineExceeded) {\n\t\t// timed out — retry with longer deadline or skip\n\t} else if isConnRefusedOrDNS(err) {\n\t\t// network/DNS issue — fail over to alternate source\n\t}\n}","preventionTips":["Health-check the site before search fan-out and skip dead sources.","Use a lower per-search timeout and rely on the plugin's internal retries.","Monitor DNS/firewall paths to the target domain."],"tags":["network","http","timeout","dns","retry-exhausted"],"backgroundTag":"network-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"}