{"record":{"id":"5351e7935ba2fb61","repo":"fish2018/pansou","slug":"s-w-5351e7","errorCode":null,"errorMessage":"[%s] 读取响应失败: %w","messagePattern":"\\[(.+?)\\] 读取响应失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/wuji/wuji.go","lineNumber":203,"sourceCode":"\t// 设置请求头\n\tp.setRequestHeaders(req)\n\t\n\t// 发送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\t\n\t// 检查状态码\n\tif resp.StatusCode != 200 {\n\t\treturn nil, fmt.Errorf(\"[%s] 请求返回状态码: %d\", p.Name(), resp.StatusCode)\n\t}\n\t\n\t// 读取响应体内容\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 读取响应失败: %w\", p.Name(), err)\n\t}\n\t\n\t// 解析HTML\n\tdoc, err := goquery.NewDocumentFromReader(strings.NewReader(string(body)))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] HTML解析失败: %w\", p.Name(), err)\n\t}\n\t\n\t// 提取搜索结果\n\treturn p.extractSearchResults(doc), nil\n}\n\n// extractSearchResults 提取搜索结果\nfunc (p *WujiPlugin) extractSearchResults(doc *goquery.Document) []model.SearchResult {\n\tvar results []model.SearchResult\n\t\n\t// 查找所有搜索结果\n\tdoc.Find(\"table.file-list tbody tr\").Each(func(i int, s *goquery.Selection) {","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/wuji/wuji.go#L185-L221","documentation":"searchPage wraps the error from io.ReadAll(resp.Body): the response body could not be fully read from the network connection. Because defer resp.Body.Close() runs right after, this typically means the connection dropped mid-transfer (unexpected EOF, connection reset by peer) or the compressed/encoded stream was corrupt.","triggerScenarios":"io.ReadAll(resp.Body) fails after a 200 response: server closed the connection mid-body, TLS truncation, proxy interference, or an interrupted read hitting the 30s context deadline.","commonSituations":"Flaky upstream site or CDN dropping large HTML pages; overloaded server truncating responses; NAT/firewall killing long-lived connections; unstable network on the host running pansou.","solutions":["Check the wrapped error (unexpected EOF vs context deadline vs connection reset)","Retry the search — transient truncation often succeeds on a second attempt","Increase MaxRetries in doRequestWithRetry to cover mid-body drops","Increase TimeoutSeconds if the deadline is being hit on large pages","Ensure no misconfigured proxy is intercepting and truncating traffic"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"results, err := p.Search(keyword, ext)\nif err != nil && strings.Contains(err.Error(), \"读取响应失败\") {\n    // transient body read failure: retry with backoff\n    time.Sleep(time.Second)\n    results, err = p.Search(keyword, ext)\n}","preventionTips":["Enable the plugin's built-in retry (MaxRetries) for transient truncation","Increase TimeoutSeconds on slow links so large pages finish downloading","Avoid unreliable proxies that terminate connections mid-body","Retry once automatically — these failures are usually transient"],"tags":["network","http","io","connection-reset","go"],"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"}