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
- Unwrap lastErr to identify the transport failure mode before changing settings.
- Verify reachability of the ASH host with curl from the deployment environment.
- Increase maxRetries/backoff or the context timeout if failures are intermittent/slow.
- 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
- Confirm upstream reachability from the deployment network before jobs
- Keep retry budget within the caller's context deadline
- Rotate egress IP/proxy when blocked
- Log the wrapped transport error, never discard it
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)