fish2018/pansou · error

API返回非200状态码

Error message

API返回非200状态码: %d

What it means

fetchPage in the bixin plugin returns this when the API responds with a status code other than 200 after all retry attempts are exhausted. It is an upstream API-level failure (e.g. 403 anti-bot block, 404, 429 rate limit, 5xx) rather than a transport error. Only the numeric code is reported, not the body, which limits diagnostics.

Solutions

  1. Log resp.StatusCode and read a snippet of the body before returning to identify 403/429/5xx causes.
  2. If 429: reduce request frequency or honor Retry-After; add exponential backoff.
  3. If 403: update request headers (User-Agent, cookies, tokens) to match what the site expects.
  4. Verify the bixin API endpoint URL is still current.

Example fix

// before
return nil, false, fmt.Errorf("API返回非200状态码: %d", resp.StatusCode)
// after
bodySnippet, _ := io.ReadAll(io.LimitReader(resp.Body, 512))
return nil, false, fmt.Errorf("API返回非200状态码: %d, body: %s", resp.StatusCode, bodySnippet)
Defensive patterns

Strategy: fallback

Validate before calling

// probe the endpoint's health before running a search batch
resp, err := http.Get(baseURL)
if err != nil || resp.StatusCode != http.StatusOK {
    log.Printf("bixin API unhealthy (status=%v)", err)
}
if resp != nil { resp.Body.Close() }

Try / catch

results, err := plugin.Search(ctx, keyword)
if err != nil {
    if strings.Contains(err.Error(), "非200状态码") {
        // extract status code, apply rate-limit/backoff or switch to fallback source
    }
}

Prevention

When it happens

Trigger: resp.StatusCode != http.StatusOK on the final retry iteration (i == p.retries) in fetchPage — e.g. repeated 429 rate limiting or a 403 from the WAF.

Common situations: Rate limiting due to too-frequent scraping, IP banned by the site's anti-bot protection, endpoint path changed upstream, or server outage.

Related errors


AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07). Data as JSON: /api/errors/db07051949f68b4f. Report an issue: GitHub.

Appendix: source

Thrown at plugin/bixin/bixin.go:228

			continue
		}
		
		defer resp.Body.Close()
		
		// 读取响应体
		responseBody, err = io.ReadAll(resp.Body)
		if err != nil {
			if i == p.retries {
				return nil, false, fmt.Errorf("读取响应失败: %w", err)
			}
			time.Sleep(500 * time.Millisecond)
			continue
		}
		
		// 状态码检查
		if resp.StatusCode != http.StatusOK {
			if i == p.retries {
				return nil, false, fmt.Errorf("API返回非200状态码: %d", resp.StatusCode)
			}
			time.Sleep(500 * time.Millisecond)
			continue
		}
		
		// 请求成功,跳出重试循环
		break
	}
	
	// 解析响应
	var apiResp BixinResponse
	if err := json.Unmarshal(responseBody, &apiResp); err != nil {
		return nil, false, fmt.Errorf("解析响应失败: %w", err)
	}
	
	// 处理结果
	results := make([]model.SearchResult, 0, len(apiResp.Data))
	postMap := make(map[string]BixinPost)

View on GitHub (pinned to beaa561337)