{"record":{"id":"b7ef05ef626ab0a6","repo":"fish2018/pansou","slug":"d-b7ef05","errorCode":null,"errorMessage":"搜索响应状态码异常: %d","messagePattern":"搜索响应状态码异常: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/libvio/libvio.go","lineNumber":140,"sourceCode":"\n// searchImpl 实际的搜索实现\nfunc (p *LibvioPlugin) searchImpl(client *http.Client, keyword string, ext map[string]interface{}) ([]model.SearchResult, error) {\n\tsearchURL := fmt.Sprintf(\"%s%s?wd=%s&submit=\", BaseURL, SearchPath, url.QueryEscape(keyword))\n\n\tif p.debugMode {\n\t\tlog.Printf(\"[Libvio] 开始搜索: %s\", keyword)\n\t\tlog.Printf(\"[Libvio] 搜索URL: %s\", searchURL)\n\t}\n\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\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"搜索响应状态码异常: %d\", resp.StatusCode)\n\t}\n\n\t// 处理响应体（可能是gzip压缩的）\n\treader, err := p.getResponseReader(resp)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// 解析HTML\n\tdoc, err := goquery.NewDocumentFromReader(reader)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"解析HTML失败: %w\", err)\n\t}\n\n\t// 提取搜索结果\n\tresults := p.extractSearchResults(doc, keyword)\n\n\tif p.debugMode {","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/libvio/libvio.go#L122-L158","documentation":"The libvio plugin's searchImpl aborts when the search HTTP response does not return status 200. The plugin treats any non-OK status as an unusable search response and returns this wrapped error containing the actual status code. It exists to surface upstream site problems (anti-bot, rate limiting, redirects) instead of parsing a garbage body.","triggerScenarios":"p.searchImpl issued a GET to the libvio site, the request succeeded, but resp.StatusCode != http.StatusOK (e.g. 403 from anti-bot protection, 429 rate limit, 5xx site error, or 30x redirect not followed).","commonSituations":"Site enabled Cloudflare/WAF challenges; plugin client not sending a browser-like User-Agent; request rate too high; site is down or path changed after a site update.","solutions":["Check the printed status code and fetch the search URL manually with curl and a browser User-Agent to reproduce","Add/refresh browser-like headers (User-Agent, Referer, Accept) on the http.Request in searchImpl","Slow down requests or add backoff/retry for 429/5xx responses","Update the site base URL or search path if the site moved (common with mirror domains)","Route the client through a proxy/cookie jar if the site geo-blocks or challenges the scraper"],"exampleFix":"// before\nreq, _ := http.NewRequest(\"GET\", searchURL, nil)\nresp, err := client.Do(req)\n// after\nreq, _ := http.NewRequest(\"GET\", searchURL, nil)\nreq.Header.Set(\"User-Agent\", \"Mozilla/5.0 (Windows NT 10.0; Win64; x64)\")\nreq.Header.Set(\"Referer\", \"https://libvio.app/\")\nresp, err := client.Do(req)","handlingStrategy":"try-catch","validationCode":"// Go: pre-check via HEAD/GET before trusting search\nresp, err := client.Get(searchURL)\nif err != nil || resp.StatusCode != http.StatusOK {\n    return fmt.Errorf(\"libvio 不可达: status=%v err=%v\", statusOf(resp), err)\n}","typeGuard":null,"tryCatchPattern":"results, err := p.Search(keyword)\nif err != nil {\n    if strings.Contains(err.Error(), \"状态码异常\") {\n        // surface status code to user, schedule retry with backoff\n        log.Printf(\"libvio search upstream error: %v\", err)\n        return fallbackResults(keyword)\n    }\n    return err\n}","preventionTips":["Send complete browser-like headers (User-Agent, Referer, Accept-Language)","Keep the plugin's base URL updated when the site changes domains","Throttle request rate to avoid 429","Monitor status codes and alert on persistent 403/5xx"],"tags":["http","network","scraping","upstream"],"backgroundTag":"http-error-response","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"}