fish2018/pansou · error

HTTP 状态码

Error message

HTTP 状态码 %d

What it means

In nsgame's doRequestWithRetry, when the underlying request produces an error after exhausting retries, this generic 'HTTP 状态码 %d' error is constructed as the lastErr. The code has a logic bug: lastErr is assigned err immediately before, so the nil check never fires and this message is effectively dead code — errors surfaced this way almost always come from err, not the status code.

Solutions

  1. Inspect the wrapped lastErr in the final '重试 %d 次后仍然失败' error to find the real cause.
  2. Fix the logic: check resp.StatusCode != http.StatusOK explicitly in the loop and build the status error there, since lastErr = err makes the nil check dead code.
  3. Verify site reachability with curl and add a proxy if needed.
  4. Reduce retry pressure (longer backoff) if the server is rate-limiting (429).

Example fix

// before
lastErr = err
if lastErr == nil {
    lastErr = fmt.Errorf("HTTP 状态码 %d", resp.StatusCode)
}
// after
if err != nil {
    lastErr = err
} else if resp.StatusCode != http.StatusOK {
    lastErr = fmt.Errorf("HTTP 状态码 %d", resp.StatusCode)
}
Defensive patterns

Strategy: retry

Validate before calling

null

Type guard

null

Try / catch

_, err := doRequestWithRetry(req, client)
if err != nil {
    root := errors.Unwrap(err)
    log.Printf("all retries exhausted, root cause: %v", root)
}

Prevention

When it happens

Trigger: Inside the retry loop, client.Do fails (or a non-OK status sets err) on every attempt; lastErr = err executes and the following 'if lastErr == nil' branch that would create this status-code error is unreachable.

Common situations: Search/detail requests repeatedly failing against nsthwj.cn — site down, rate-limited, or network broken — then wrapped by error 463 ('重试 %d 次后仍然失败').

Related errors


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

Appendix: source

Thrown at plugin/nsgame/nsgame.go:506

			// 指数退避重试
			backoff := time.Duration(1<<uint(i-1)) * 200 * time.Millisecond
			time.Sleep(backoff)
		}

		// 克隆请求避免并发问题
		reqClone := req.Clone(req.Context())

		resp, err := client.Do(reqClone)
		if err == nil && resp.StatusCode == 200 {
			return resp, nil
		}

		if resp != nil {
			resp.Body.Close()
		}
		lastErr = err
		if lastErr == nil {
			lastErr = fmt.Errorf("HTTP 状态码 %d", resp.StatusCode)
		}
	}

	return nil, fmt.Errorf("重试 %d 次后仍然失败: %w", maxRetries, lastErr)
}

View on GitHub (pinned to beaa561337)