{"record":{"id":"451a68d5e0cfd33d","repo":"fish2018/pansou","slug":"s-read-response-failed-on-page-d-w","errorCode":null,"errorMessage":"[%s] read response failed on page %d: %w","messagePattern":"\\[(.+?)\\] read response failed on page (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/discourse/discourse.go","lineNumber":243,"sourceCode":"\t\tif resp.StatusCode != 200 {\n\t\t\tresp.Body.Close()\n\t\t\t// 如果已经获取到一些结果，返回已有结果\n\t\t\tif len(allResults) > 0 {\n\t\t\t\tfmt.Printf(\"[%s] Warning: unexpected status code %d on page %d\\n\", p.Name(), resp.StatusCode, currentPage)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn nil, fmt.Errorf(\"[%s] unexpected status code: %d on page %d\", p.Name(), resp.StatusCode, currentPage)\n\t\t}\n\n\t\t// 读取响应体\n\t\tbody, err := io.ReadAll(resp.Body)\n\t\tresp.Body.Close()\n\t\tif err != nil {\n\t\t\tif len(allResults) > 0 {\n\t\t\t\tfmt.Printf(\"[%s] Warning: failed to read page %d: %v\\n\", p.Name(), currentPage, err)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn nil, fmt.Errorf(\"[%s] read response failed on page %d: %w\", p.Name(), currentPage, err)\n\t\t}\n\n\t\t// 解析JSON响应\n\t\tvar searchResp SearchResponse\n\t\tif err := json.Unmarshal(body, &searchResp); err != nil {\n\t\t\tif len(allResults) > 0 {\n\t\t\t\tfmt.Printf(\"[%s] Warning: failed to parse page %d: %v\\n\", p.Name(), currentPage, err)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn nil, fmt.Errorf(\"[%s] parse json failed on page %d: %w\", p.Name(), currentPage, err)\n\t\t}\n\n\t\t// 如果没有帖子了，停止获取\n\t\tif len(searchResp.Posts) == 0 {\n\t\t\tbreak\n\t\t}\n\t\t\n\t\t// 转换为SearchResult并去重","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/discourse/discourse.go#L225-L261","documentation":"searchImpl fetches Discourse search pages and reads each response body with io.ReadAll. If reading the body fails on the first page (no results yet), it returns this error wrapping the underlying read error with the page number; otherwise it logs a warning and stops.","triggerScenarios":"io.ReadAll(resp.Body) returns an error during pagination of Discourse search results, with allResults empty.","commonSituations":"Connection reset or timeout mid-response, server closing the connection early (truncated chunked response), or network flakiness on mobile/unstable links.","solutions":["Retry the search; transient network resets are the usual cause","Check network stability/proxy configuration","Increase the request timeout if large pages are being truncated","If partial results are acceptable, rely on the warning path that keeps already-fetched results"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"links, err := plugin.Search(query)\nif err != nil && strings.Contains(err.Error(), \"read response failed\") {\n    time.Sleep(2 * time.Second)\n    links, err = plugin.Search(query) // transient read failures usually succeed on retry\n}","preventionTips":["Use stable networks or retries for flaky connections","Avoid overly tight client timeouts on slow forums","Prefer partial-result tolerance in your own wrapper"],"tags":["network","io","http","discourse"],"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"}