fish2018/pansou · error

重试 次后仍然失败

Error message

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

What it means

ash's doRequestWithRetry loops until the request succeeds, maxRetries is hit, or the request context is cancelled. After the loop, if lastErr is non-nil it returns '重试 %d 次后仍然失败: %w' with the final transport error wrapped. This variant carries the root cause; the plain variant (error 38) fires only when the loop exited via context cancellation without recording lastErr.

Solutions

  1. Unwrap lastErr to identify the transport failure mode before changing settings.
  2. Verify reachability of the ASH host with curl from the deployment environment.
  3. Increase maxRetries/backoff or the context timeout if failures are intermittent/slow.
  4. Add proxy or IP rotation if the site blocks the current egress address.

Example fix

// before
return nil, fmt.Errorf("重试 %d 次后仍然失败: %w", maxRetries, lastErr)
// after
return nil, fmt.Errorf("重试 %d 次后仍然失败(%s): %w", maxRetries, classifyNetErr(lastErr), lastErr)
Defensive patterns

Strategy: retry

Validate before calling

func isRetryable(err error) bool { var ne net.Error; return errors.As(err, &ne) || errors.Is(err, syscall.ECONNREFUSED) }

Try / catch

if err != nil {
    cause := errors.Unwrap(err)
    if isConnRefused(cause) { failFast() } else if isTimeout(cause) { retryWithLongerDeadline() }
}

Prevention

When it happens

Trigger: All retry attempts of the GET request fail (connection refused/reset, DNS, TLS, timeout) so lastErr is set when the loop ends, or the context expires with a last attempt error present — ash.go:304.

Common situations: Upstream fully unreachable (site down, blocked IP); every attempt hits the 15s context deadline; persistent 5xx handled as retryable errors inside the loop.

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/837169282c8e74ea. Report an issue: GitHub.

Appendix: source

Thrown at plugin/ash/ash.go:304

		if err == nil && resp.StatusCode == 200 {
			return resp, nil
		}
		
		// 清理响应
		if resp != nil {
			resp.Body.Close()
		}
		
		lastErr = err
		
		// 如果是上下文取消或超时,不再重试
		if req.Context().Err() != nil {
			break
		}
	}
	
	if lastErr != nil {
		return nil, fmt.Errorf("重试 %d 次后仍然失败: %w", maxRetries, lastErr)
	}
	
	return nil, fmt.Errorf("重试 %d 次后仍然失败", maxRetries)
}

View on GitHub (pinned to beaa561337)