fish2018/pansou · error
[ ] 搜索返回状态码
Error message
[%s] 搜索返回状态码: %d
What it means
This error is returned by MikuclubPlugin.fetchCategoryPosts when the WordPress search API (https://www.mikuclub.uk/wp-json/utils/v2/post_list) responds with a status code other than 200. The plugin aborts the category search instead of trying to decode a body that is not a valid postListResponse. The numeric code is embedded in the message so the caller can distinguish 403/429/5xx etc.
Solutions
- Inspect the numeric status in the message; for 403/429 wait or reduce request rate, for 5xx retry later
- Check https://www.mikuclub.uk directly in a browser to confirm the API is up
- Update setCommonHeaders (User-Agent/Referer) to match a real browser if protection was added
- Re-run the search; the plugin already retries via doRequestWithRetry with exponential backoff
Example fix
// before (caller sees raw error)
results, err := plugin.Search("keyword", nil)
// after (caller classifies status)
results, err := plugin.Search("keyword", nil)
if err != nil {
if strings.Contains(err.Error(), "状态码: 429") {
time.Sleep(time.Minute) // back off on rate limit
}
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
// Go: check upstream health before searching
resp, err := http.Head("https://www.mikuclub.uk/")
if err != nil || resp.StatusCode != http.StatusOK {
// skip search, site is down or blocking
} Type guard
func isUpstreamStatusError(err error) bool {
return err != nil && strings.Contains(err.Error(), "搜索返回状态码")
} Try / catch
results, err := plugin.Search(keyword, nil)
if err != nil {
if isUpstreamStatusError(err) {
log.Printf("mikuclub unavailable: %v", err)
return fallbackResults, nil
}
return nil, err
} Prevention
- Rate-limit searches to avoid 429s
- Monitor upstream site availability before batch runs
- Keep browser-like User-Agent/Referer headers current
- Treat 5xx as transient and schedule retries
When it happens
Trigger: fetchCategoryPosts calls doRequestWithRetry and the final HTTP response has StatusCode != http.StatusOK, e.g. the site returns 403 (bot protection / Anubis-like gate), 429 (rate limited), 500 (server error), or 404 after retries exhausted.
Common situations: The mikuclub.uk upstream site is down or under maintenance; anti-scraping protection blocks the plugin's default headers; too-aggressive keyword searching triggers rate limiting; network middleboxes/proxies inject 502/503 responses.
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
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/9be97f2ca8e997e2.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/mikuclub/mikuclub.go:253
reqURL := fmt.Sprintf("https://www.mikuclub.uk/wp-json/utils/v2/post_list?%s", params.Encode())
ctx, cancel := context.WithTimeout(context.Background(), searchTimeout)
defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, reqURL, nil)
if err != nil {
return nil, fmt.Errorf("[%s] 创建搜索请求失败: %w", p.Name(), err)
}
setCommonHeaders(req, "https://www.mikuclub.uk/")
resp, err := p.doRequestWithRetry(req, client, searchMaxRetries)
if err != nil {
return nil, fmt.Errorf("[%s] 搜索请求失败: %w", p.Name(), err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("[%s] 搜索返回状态码: %d", p.Name(), resp.StatusCode)
}
var payload postListResponse
if err := json.NewDecoder(resp.Body).Decode(&payload); err != nil {
return nil, fmt.Errorf("[%s] 解析搜索结果失败: %w", p.Name(), err)
}
return payload.Posts, nil
}
func (p *MikuclubPlugin) fetchDetailLinks(client *http.Client, postID int64, detailURL string) []model.Link {
if cached, ok := detailCache.Load(postID); ok {
if entry, valid := cached.(cacheEntry); valid {
if time.Now().Before(entry.expiresAt) && len(entry.links) > 0 {
return entry.links
}
detailCache.Delete(postID)
}View on GitHub (pinned to beaa561337)