{"record":{"id":"f264207172463393","repo":"fish2018/pansou","slug":"w-f26420","errorCode":null,"errorMessage":"发送搜索请求失败: %w","messagePattern":"发送搜索请求失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/leijing/leijing.go","lineNumber":132,"sourceCode":"\t\tlog.Printf(\"[Leijing] 响应状态: %d\", resp.StatusCode)\n\t}\n\t\n\treturn resp, nil\n}\n\n// searchImpl 实际的搜索实现\nfunc (p *LeijingPlugin) searchImpl(client *http.Client, keyword string, ext map[string]interface{}) ([]model.SearchResult, error) {\n\tsearchURL := fmt.Sprintf(\"%s%s?keyword=%s\", BaseURL, SearchPath, url.QueryEscape(keyword))\n\t\n\tif p.debugMode {\n\t\tlog.Printf(\"[Leijing] 开始搜索: %s\", keyword)\n\t\tlog.Printf(\"[Leijing] 搜索URL: %s\", searchURL)\n\t}\n\t\n\t// 发送搜索请求\n\tresp, err := p.doRequest(client, searchURL, BaseURL)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"发送搜索请求失败: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\t\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"搜索响应状态码异常: %d\", resp.StatusCode)\n\t}\n\t\n\t// 处理响应体（可能是gzip压缩的）\n\treader, err := p.getResponseReader(resp)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t\n\t// 解析HTML\n\tdoc, err := goquery.NewDocumentFromReader(reader)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"解析HTML失败: %w\", err)\n\t}","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/leijing/leijing.go#L114-L150","documentation":"searchImpl in the leijing plugin wraps any error from p.doRequest (which performs the HTTP GET against the search URL) with this message. It signals the HTTP request itself failed before a response was obtained. The original transport error is preserved via %w.","triggerScenarios":"p.doRequest(client, searchURL, BaseURL) returns a non-nil error during a keyword search: connection refused/reset, timeout, DNS failure, TLS error, or proxy failure.","commonSituations":"The leijing upstream site is unreachable or has changed domain; corporate firewall blocks egress; client timeout too short; site requires different TLS settings (e.g. TLS fingerprinting blocked Go's default client).","solutions":["Inspect the wrapped cause from %w to see the transport-level reason","Test the search URL with curl from the same host to confirm reachability","Increase the HTTP client timeout or configure a proxy if egress is restricted","Check if the site blocks automated clients and adjust headers (User-Agent, Referer)","If the domain changed, update the BaseURL/searchURL constants in the plugin"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"u, err := url.Parse(searchURL)\nif err != nil || u.Host == \"\" {\n    return fmt.Errorf(\"invalid search URL: %q\", searchURL)\n}","typeGuard":null,"tryCatchPattern":"results, err := plugin.Search(ctx, keyword)\nif err != nil {\n    if errors.Is(err, context.DeadlineExceeded) {\n        return fmt.Errorf(\"leso search timed out: %w\", err)\n    }\n    var netErr net.Error\n    if errors.As(err, &netErr) && netErr.Timeout() {\n        // retry with a longer timeout\n    }\n    return err\n}","preventionTips":["Health-check the upstream domain before registering the plugin","Keep the HTTP client timeout above the site's p95 latency","Pin and periodically re-verify the BaseURL for domain changes","Use a realistic User-Agent to reduce bot-blocking","Log errors.Unwrap(err) so transport causes are diagnosable"],"tags":["go","http","network","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"}