fish2018/pansou · error

重试 次后仍然失败

Error message

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

What it means

doRequestWithRetry exhausts maxRetries attempts without a successful response and returns "重试 %d 次后仍然失败" wrapping the last error (either a transport error or the synthesized "HTTP 状态码 %d"). It signals the caller that the request failed permanently after all retries.

Solutions

  1. Unwrap the cause (errors.Unwrap) to distinguish transport failure from a bad HTTP status.
  2. Increase maxRetries and add exponential backoff with jitter between attempts.
  3. Verify reachability of the target host (curl/DNS) and check for proxy/firewall blocking.
  4. If 403/429 persist, rotate User-Agent/cookies or respect rate limits before retrying.
  5. Surface the error to the user as 'source temporarily unavailable' and allow the caller to retry later.

Example fix

// before
resp, err := p.doRequestWithRetry(req, client)
if err != nil {
    return nil, err
}
// after
resp, err := p.doRequestWithRetry(req, client)
if err != nil {
    return nil, fmt.Errorf("source unavailable after retries: %w", err) // caller can retry later
}
Defensive patterns

Strategy: retry

Try / catch

results, err := plugin.Search(ctx, keyword)
if err != nil {
    if strings.Contains(err.Error(), "重试") {
        // all retries exhausted — schedule a later retry with backoff
        return nil, fmt.Errorf("source temporarily unavailable: %w", err)
    }
    return nil, err
}

Prevention

When it happens

Trigger: fetchSearchResults or getDownloadLinks issues a request that fails on every attempt: persistent network outage, site hard-blocking the client, sustained 5xx, or retries exhausted faster than the outage lasted.

Common situations: Site is down for maintenance, IP rate-limited/banned across the whole retry window, corporate proxy blocking the domain, or maxRetries too low for a flaky connection.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


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

Appendix: source

Thrown at plugin/cyg/cyg.go:399

		// 克隆请求避免并发问题
		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 err == nil {
			lastErr = fmt.Errorf("HTTP 状态码 %d", resp.StatusCode)
		}
	}

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

// parseExtOptions 从ext参数中解析搜索选项
func (p *CygPlugin) parseExtOptions(ext map[string]interface{}) CygSearchOptions {
	opts := CygSearchOptions{
		PerPage: 20,
		Page:    1,
		OrderBy: "date",
		Order:   "desc",
	}

	if ext == nil {
		return opts
	}

	if perPage, ok := ext["per_page"].(int); ok && perPage > 0 {
		opts.PerPage = perPage
	}

View on GitHub (pinned to beaa561337)