fish2018/pansou · error
[ ] unexpected status code: on page
Error message
[%s] unexpected status code: %d on page %d
What it means
searchImpl paginates the Discourse /search.json API. If a page returns a non-2xx status code and no results have been accumulated yet, the plugin aborts and returns this error wrapping the plugin name, status code, and page number. If some results were already collected, it only logs a warning and stops instead.
Solutions
- Check the status code printed in the error; if 403/503 the site's Cloudflare protection likely rejected the request — verify scraper/cloudscraper initialization and cookies
- Reduce pagination speed or page count to avoid 429 rate limiting
- Verify the configured Discourse base URL is correct and reachable in a browser
- Retry later if the forum is temporarily down (5xx)
- If partial results are acceptable, rely on the warning path (results already present) instead of failing
Example fix
// before
if resp.StatusCode != 200 {
return nil, fmt.Errorf("[%s] unexpected status code: %d on page %d", p.Name(), resp.StatusCode, currentPage)
}
// after
if resp.StatusCode == 429 {
time.Sleep(retryBackoff)
continue // retry the same page
} else if resp.StatusCode != 200 {
return nil, fmt.Errorf("[%s] unexpected status code: %d on page %d", p.Name(), resp.StatusCode, currentPage)
} Defensive patterns
Strategy: retry
Validate before calling
// optionally pre-check the site is reachable
resp, err := http.Get(baseURL + "/about.json")
if err != nil || resp.StatusCode != 200 {
return fmt.Errorf("discourse site unreachable: status=%d err=%v", statusOf(resp), err)
} Try / catch
links, err := plugin.Search(query)
if err != nil {
if strings.Contains(err.Error(), "unexpected status code") {
// parse code, backoff and retry once for 429/5xx
time.Sleep(backoff)
links, err = plugin.Search(query)
}
if err != nil {
return fmt.Errorf("search failed: %w", err)
}
} Prevention
- Keep request rates low to avoid 429s
- Keep cloudscraper sessions/cookies fresh for Cloudflare-protected sites
- Validate the configured forum base URL before searching
- Handle partial results: the plugin warns instead of erroring once some pages succeeded
When it happens
Trigger: Calling Search (via searchImpl) when a Discourse search page request returns e.g. 403, 429, or 500 on the first page fetched (allResults empty).
Common situations: Site blocks requests due to missing/rotated Cloudflare clearance, rate limiting from too-fast pagination, forum being temporarily down, or an incorrect base URL hitting an error page.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- [ ] search request failed on page
- [ ] read response failed on page
- detail request failed
- read response failed
- [ ] 第 页搜索请求失败
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/bc3222aeed88ad7f.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/discourse/discourse.go:232
resp, err := p.scraper.Get(searchURL)
if err != nil {
// 如果已经获取到一些结果,返回已有结果而不是报错
if len(allResults) > 0 {
fmt.Printf("[%s] Warning: failed to fetch page %d: %v\n", p.Name(), currentPage, err)
break
}
return nil, fmt.Errorf("[%s] search request failed on page %d: %w", p.Name(), currentPage, err)
}
// 检查HTTP状态码
if resp.StatusCode != 200 {
resp.Body.Close()
// 如果已经获取到一些结果,返回已有结果
if len(allResults) > 0 {
fmt.Printf("[%s] Warning: unexpected status code %d on page %d\n", p.Name(), resp.StatusCode, currentPage)
break
}
return nil, fmt.Errorf("[%s] unexpected status code: %d on page %d", p.Name(), resp.StatusCode, currentPage)
}
// 读取响应体
body, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
if len(allResults) > 0 {
fmt.Printf("[%s] Warning: failed to read page %d: %v\n", p.Name(), currentPage, err)
break
}
return nil, fmt.Errorf("[%s] read response failed on page %d: %w", p.Name(), currentPage, err)
}
// 解析JSON响应
var searchResp SearchResponse
if err := json.Unmarshal(body, &searchResp); err != nil {
if len(allResults) > 0 {
fmt.Printf("[%s] Warning: failed to parse page %d: %v\n", p.Name(), currentPage, err)View on GitHub (pinned to beaa561337)