fish2018/pansou · error

[ ] 请求返回状态码

Error message

[%s] 请求返回状态码: %d

What it means

The NSGame search API returned an HTTP status code other than 200; the plugin treats any non-200 as a hard failure and surfaces the raw code. This happens after the request itself succeeded (no transport error), meaning the server actively responded with an error or redirect/anti-bot page status.

Solutions

  1. Log resp.Status and a body snippet on non-200 to identify the actual blocker (WAF page vs 5xx)
  2. Reduce request frequency / add jittered backoff if 429
  3. Check whether nsthwj.cn changed its API path and update apiURL
  4. Send the session headers/cookies produced by ensureSession (setRequestHeaders with Referer https://nsthwj.cn/) exactly as a browser would to pass WAF checks
  5. Retry later if it's a 5xx outage

Example fix

// before
if resp.StatusCode != 200 {
    return nil, fmt.Errorf("[%s] 请求返回状态码: %d", p.Name(), resp.StatusCode)
}
// after
if resp.StatusCode != 200 {
    snippet, _ := io.ReadAll(io.LimitReader(resp.Body, 256))
    return nil, fmt.Errorf("[%s] 请求返回状态码: %d, body: %s", p.Name(), resp.StatusCode, snippet)
}
Defensive patterns

Strategy: retry

Validate before calling

// preemptive check of upstream health
resp, err := http.Get("https://nsthwj.cn/")
if err == nil && resp.StatusCode == http.StatusForbidden {
    log.Warn("upstream WAF is blocking this IP")
}
if resp != nil { resp.Body.Close() }

Try / catch

results, err := plugin.Search(keyword, ext)
var statusErr *plugin.StatusError
if errors.As(err, &statusErr) && statusErr.Code == 429 {
    time.Sleep(backoff)
    // retry once
}

Prevention

When it happens

Trigger: Server responds 403/429/503 from anti-bot or rate limiting, 5xx from upstream outage, 404 when the apiURL path changed, or 302/301 if the client follows redirects to an HTML page with an error status.

Common situations: The site deployed Cloudflare/WAF challenge returning 403, scraping too aggressively triggering 429, site maintenance returning 502/503, or the plugin's hardcoded apiURL changed after a site update.

Related errors


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

Appendix: source

Thrown at plugin/nsgame/nsgame.go:167

	if err != nil {
		return nil, fmt.Errorf("[%s] 创建请求失败: %w", p.Name(), err)
	}

	// 4. 设置请求头
	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36")
	req.Header.Set("Accept", "application/json, text/plain, */*")
	req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8")
	p.setRequestHeaders(req, "https://nsthwj.cn/")

	// 5. 发送请求(带重试机制)
	resp, err := p.doRequestWithRetry(req, client)
	if err != nil {
		return nil, fmt.Errorf("[%s] 搜索请求失败: %w", p.Name(), err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("[%s] 请求返回状态码: %d", p.Name(), resp.StatusCode)
	}

	// 6. 读取响应体
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("[%s] 读取响应失败: %w", p.Name(), err)
	}

	// 7. 解析JSON响应
	var apiResp NSGameResponse
	if err := json.Unmarshal(body, &apiResp); err != nil {
		return nil, fmt.Errorf("[%s] JSON解析失败: %w", p.Name(), err)
	}

	// 8. 检查响应状态
	if !apiResp.Success || (apiResp.Code != "" && apiResp.Code != "200") {
		return nil, fmt.Errorf("[%s] API返回错误: success=%v, code=%s", p.Name(), apiResp.Success, apiResp.Code)
	}

View on GitHub (pinned to beaa561337)