{"record":{"id":"a439dc919f89a202","repo":"fish2018/pansou","slug":"s-search-request-failed-on-page-d-w","errorCode":null,"errorMessage":"[%s] search request failed on page %d: %w","messagePattern":"\\[(.+?)\\] search request failed on page (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/discourse/discourse.go","lineNumber":221,"sourceCode":"\t// 循环获取多页\n\tfor currentPage := startPage; currentPage < startPage+maxPages; currentPage++ {\n\t\tfetchedPages++\n\t\t// 如果不是第一页，添加延迟避免请求过快\n\t\tif currentPage > startPage {\n\t\t\ttime.Sleep(pageRequestDelay)\n\t\t}\n\t\t\n\t\tsearchURL := fmt.Sprintf(searchURLTemplate, encodedKeyword, currentPage)\n\t\t\n\t\t// 发送搜索请求\n\t\tresp, err := p.scraper.Get(searchURL)\n\t\tif err != nil {\n\t\t\t// 如果已经获取到一些结果，返回已有结果而不是报错\n\t\t\tif len(allResults) > 0 {\n\t\t\t\tfmt.Printf(\"[%s] Warning: failed to fetch 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] search request failed on page %d: %w\", p.Name(), currentPage, err)\n\t\t}\n\n\t\t// 检查HTTP状态码\n\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 {","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/discourse/discourse.go#L203-L239","documentation":"During paginated search, when a page request fails and NO results have been collected yet (allResults is empty), searchImpl returns this wrapped error including the plugin name and page number. If some pages already succeeded, the plugin instead logs a warning and returns partial results — this error only fires on a total failure with nothing to show.","triggerScenarios":"The HTTP fetch for page currentPage errors while len(allResults) == 0 — e.g. page 1 itself is unreachable, times out, or the scraper fails — so there are no partial results to fall back on.","commonSituations":"Discourse instance down or DNS broken; first-page request blocked by Cloudflare/rate limiting; max_pages configured but the instance rejects the first request; transient network outage during the initial request.","solutions":["Unwrap the error to identify the root cause (timeout, connection, HTTP error).","Retry the search; if it's transient, a later attempt may succeed.","Reduce max_pages or add inter-page delays if throttling is suspected.","Verify the Discourse base URL and that the instance is reachable from the host."],"exampleFix":"// before\nresults, err := p.Search(keyword)\nif err != nil { return err }\n// after\nresults, err := p.Search(keyword)\nif err != nil {\n    var netErr net.Error\n    if errors.As(err, &netErr) && netErr.Timeout() {\n        return retryLater(err) // transient first-page failure\n    }\n    return err\n}","handlingStrategy":"retry","validationCode":"resp, err := http.Get(baseURL + \"/about.json\")\nif err != nil {\n    return fmt.Errorf(\"discourse instance unreachable before search: %w\", err)\n}\nresp.Body.Close()","typeGuard":null,"tryCatchPattern":"if err != nil {\n    var netErr net.Error\n    if errors.As(err, &netErr) && netErr.Timeout() {\n        return retryAfterDelay(err, 30*time.Second)\n    }\n    return err\n}","preventionTips":["Health-check the Discourse instance before starting paginated searches.","Cap max_pages and add delays between page requests to avoid throttling.","Distinguish total failures (this error) from partial failures and handle them separately."],"tags":["http","pagination","network","discourse","go"],"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"}