{"record":{"id":"9bc82d38f4e88162","repo":"fish2018/pansou","slug":"s-w-9bc82d","errorCode":null,"errorMessage":"[%s] 搜索请求失败: %w","messagePattern":"\\[(.+?)\\] 搜索请求失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/jutoushe/jutoushe.go","lineNumber":70,"sourceCode":"\tdefer cancel()\n\n\t// 3. 创建请求对象\n\treq, err := http.NewRequestWithContext(ctx, \"GET\", searchURL, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 创建请求失败: %w\", p.Name(), err)\n\t}\n\n\t// 4. 设置请求头，避免反爬虫检测\n\treq.Header.Set(\"User-Agent\", \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36\")\n\treq.Header.Set(\"Accept\", \"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\")\n\treq.Header.Set(\"Accept-Language\", \"zh-CN,zh;q=0.9,en;q=0.8\")\n\treq.Header.Set(\"Connection\", \"keep-alive\")\n\treq.Header.Set(\"Referer\", baseURL+\"/\")\n\n\t// 5. 发送HTTP请求（带重试机制）\n\tresp, err := p.doRequestWithRetry(req, client)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 搜索请求失败: %w\", p.Name(), err)\n\t}\n\tdefer resp.Body.Close()\n\n\t// 6. 检查状态码\n\tif resp.StatusCode != 200 {\n\t\treturn nil, fmt.Errorf(\"[%s] 请求返回状态码: %d\", p.Name(), resp.StatusCode)\n\t}\n\n\t// 7. 解析搜索结果页面\n\tdoc, err := goquery.NewDocumentFromReader(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] HTML解析失败: %w\", p.Name(), err)\n\t}\n\n\t// 8. 提取搜索结果\n\tvar results []model.SearchResult\n\tdoc.Find(\"ul.erx-list li.item\").Each(func(i int, s *goquery.Selection) {\n\t\t// 提取标题和链接","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/jutoushe/jutoushe.go#L52-L88","documentation":"jutoushe searchImpl wraps the error returned by doRequestWithRetry — meaning the HTTP request to the site failed after all internal retries (connection errors, TLS errors, timeouts). The wrapped lastErr explains the network-level cause.","triggerScenarios":"p.doRequestWithRetry(req, client) exhausts its retries: server unreachable, DNS failure, TLS handshake error, or context timeout (30s) expires mid-flight.","commonSituations":"Target site blocked or down; no internet/DNS in the deployment environment; site rate-limiting the scraper's IP; 30s context too short on slow networks.","solutions":["Inspect the wrapped error for the root cause (dial tcp / timeout / x509)","Test connectivity to the site from the host (curl baseURL)","Increase the 30s context timeout if on slow networks","Check whether the site is blocking the User-Agent/IP and adjust headers or use a proxy"],"exampleFix":"// before\nresp, err := p.doRequestWithRetry(req, client)\nif err != nil { return nil, fmt.Errorf(\"[%s] 搜索请求失败: %w\", p.Name(), err) }\n// after\nresp, err := p.doRequestWithRetry(req, client)\nif err != nil {\n    var ne net.Error\n    if errors.As(err, &ne) && ne.Timeout() {\n        return nil, fmt.Errorf(\"[%s] search timed out: %w\", p.Name(), err)\n    }\n    return nil, fmt.Errorf(\"[%s] 搜索请求失败: %w\", p.Name(), err)\n}","handlingStrategy":"retry","validationCode":"conn, err := net.DialTimeout(\"tcp\", \"www.jutoushe.cc:443\", 5*time.Second)\nif err != nil { return fmt.Errorf(\"site unreachable before search: %w\", err) }\nconn.Close()","typeGuard":null,"tryCatchPattern":"results, err := plugin.Search(keyword)\nif err != nil {\n    var ne net.Error\n    if errors.As(err, &ne) && ne.Timeout() {\n        return retryLater(err) // back off and retry later\n    }\n    return err\n}","preventionTips":["Monitor target site reachability before scheduling scrapes","Use generous but bounded timeouts (30s is reasonable)","Retry with exponential backoff and jitter","Fall back to alternative sources on persistent failure"],"tags":["go","http","network","plugin"],"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"}