fish2018/pansou · error

[ ] 重试 次后仍然失败

Error message

[%s] 重试 %d 次后仍然失败: %w

What it means

doRequestWithRetry exhausted all its retry attempts without receiving a 200 response. The final underlying cause (transport error or the last non-200 status, e.g. 'HTTP状态码: %d') is wrapped by %w. The plugin's search cannot complete without a successful HTTP response.

Solutions

  1. Read the wrapped cause to distinguish transport failure (network) from HTTP status failure (server/bot protection).
  2. Test connectivity to the target host from the same machine (curl -v).
  3. Update cookies, User-Agent, or use a proxy if the site is blocking the client.
  4. Wait and retry — for 5xx/429 the upstream often recovers; consider longer backoff.
Defensive patterns

Strategy: retry

Validate before calling

// pre-flight reachability check
if _, err := http.Head(targetURL); err != nil {
    log.Printf("target unreachable, aborting early: %v", err)
}

Try / catch

results, err := searchImpl(keyword)
if err != nil {
    if strings.Contains(err.Error(), "重试") {
        log.Printf("exhausted retries, serving cached results: %v", err)
        return cachedResults(), nil
    }
    return err
}

Prevention

When it happens

Trigger: doRequestWithRetry: after maxRetries attempts, every client.Do call either returned a transport error or a non-200 status code.

Common situations: Target site down or geo-blocked, DNS failure, local network/proxy outage, persistent 403/429 from anti-bot protection, TLS handshake failures.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at plugin/feikuai/feikuai.go:544

			time.Sleep(backoff)
		}

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

		resp, err := client.Do(reqClone)
		if err == nil {
			if resp.StatusCode == 200 {
				return resp, nil
			}
			resp.Body.Close()
			lastErr = fmt.Errorf("HTTP状态码: %d", resp.StatusCode)
		} else {
			lastErr = err
		}
	}

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

View on GitHub (pinned to beaa561337)