diff --git a/crates/uv-client/src/base_client.rs b/crates/uv-client/src/base_client.rs index be50a34de..bf662e295 100644 --- a/crates/uv-client/src/base_client.rs +++ b/crates/uv-client/src/base_client.rs @@ -608,7 +608,11 @@ impl BaseClient { /// The [`RetryPolicy`] for the client. pub fn retry_policy(&self) -> ExponentialBackoff { - ExponentialBackoff::builder().build_with_max_retries(self.retries) + let mut builder = ExponentialBackoff::builder(); + if env::var_os(EnvVars::UV_TEST_NO_HTTP_RETRY_DELAY).is_some() { + builder = builder.retry_bounds(Duration::from_millis(0), Duration::from_millis(0)); + } + builder.build_with_max_retries(self.retries) } } diff --git a/crates/uv-client/src/cached_client.rs b/crates/uv-client/src/cached_client.rs index 59b32184f..0f32aa51f 100644 --- a/crates/uv-client/src/cached_client.rs +++ b/crates/uv-client/src/cached_client.rs @@ -687,13 +687,15 @@ impl CachedClient { let total_retries = past_retries + middleware_retries; let retry_decision = retry_policy.should_retry(start_time, total_retries); if let reqwest_retry::RetryDecision::Retry { execute_after } = retry_decision { - debug!( - "Transient failure while handling response from {}; retrying...", - req.url(), - ); let duration = execute_after .duration_since(SystemTime::now()) .unwrap_or_else(|_| Duration::default()); + + debug!( + "Transient failure while handling response from {}; retrying after {:.1}s...", + req.url(), + duration.as_secs_f32(), + ); tokio::time::sleep(duration).await; past_retries += 1; continue; @@ -745,13 +747,14 @@ impl CachedClient { let total_retries = past_retries + middleware_retries; let retry_decision = retry_policy.should_retry(start_time, total_retries); if let reqwest_retry::RetryDecision::Retry { execute_after } = retry_decision { - debug!( - "Transient failure while handling response from {}; retrying...", - req.url(), - ); let duration = execute_after .duration_since(SystemTime::now()) .unwrap_or_else(|_| Duration::default()); + debug!( + "Transient failure while handling response from {}; retrying after {}s...", + req.url(), + duration.as_secs(), + ); tokio::time::sleep(duration).await; past_retries += 1; continue; diff --git a/crates/uv-publish/src/lib.rs b/crates/uv-publish/src/lib.rs index 4ab09c4f2..ea2e1c095 100644 --- a/crates/uv-publish/src/lib.rs +++ b/crates/uv-publish/src/lib.rs @@ -409,11 +409,15 @@ pub async fn upload( if UvRetryableStrategy.handle(&result) == Some(Retryable::Transient) { let retry_decision = retry_policy.should_retry(start_time, n_past_retries); if let reqwest_retry::RetryDecision::Retry { execute_after } = retry_decision { - warn_user!("Transient failure while handling response for {registry}; retrying..."); reporter.on_upload_complete(idx); let duration = execute_after .duration_since(SystemTime::now()) .unwrap_or_else(|_| Duration::default()); + warn_user!( + "Transient failure while handling response for {}; retrying after {}s...", + registry, + duration.as_secs() + ); tokio::time::sleep(duration).await; n_past_retries += 1; continue; diff --git a/crates/uv-python/src/downloads.rs b/crates/uv-python/src/downloads.rs index fb5129030..484276d1c 100644 --- a/crates/uv-python/src/downloads.rs +++ b/crates/uv-python/src/downloads.rs @@ -973,13 +973,14 @@ impl ManagedPythonDownload { if let reqwest_retry::RetryDecision::Retry { execute_after } = retry_decision { - debug!( - "Transient failure while handling response for {}; retrying...", - self.key() - ); let duration = execute_after .duration_since(SystemTime::now()) .unwrap_or_else(|_| Duration::default()); + debug!( + "Transient failure while handling response for {}; retrying after {}s...", + self.key(), + duration.as_secs() + ); tokio::time::sleep(duration).await; retried_here = true; continue; // Retry.