diff --git a/crates/cli/commands/src/download/mod.rs b/crates/cli/commands/src/download/mod.rs index 639d087aea..17a1cf7f70 100644 --- a/crates/cli/commands/src/download/mod.rs +++ b/crates/cli/commands/src/download/mod.rs @@ -1520,6 +1520,7 @@ fn blocking_process_modular_archive( } let format = CompressionFormat::from_url(&archive.file_name)?; + let mut last_error: Option = None; for attempt in 1..=MAX_DOWNLOAD_RETRIES { cleanup_output_files(target_dir, &archive.output_files); @@ -1527,13 +1528,31 @@ fn blocking_process_modular_archive( let cache_dir = cache_dir.ok_or_else(|| eyre::eyre!("Missing cache directory"))?; let archive_path = cache_dir.join(&archive.file_name); let part_path = cache_dir.join(format!("{}.part", archive.file_name)); - let (downloaded_path, _downloaded_size) = - resumable_download(&archive.url, cache_dir, shared.as_ref(), cancel_token.clone())?; - let file = fs::open(&downloaded_path)?; - extract_archive_raw(file, format, target_dir)?; + let result = + resumable_download(&archive.url, cache_dir, shared.as_ref(), cancel_token.clone()) + .and_then(|(downloaded_path, _)| { + let file = fs::open(&downloaded_path)?; + extract_archive_raw(file, format, target_dir) + }); let _ = fs::remove_file(&archive_path); let _ = fs::remove_file(&part_path); + + if let Err(e) = result { + warn!(target: "reth::cli", + file = %archive.file_name, + component = %planned.component, + attempt, + err = %e, + "Download or extraction failed, retrying" + ); + last_error = Some(e); + if attempt < MAX_DOWNLOAD_RETRIES { + std::thread::sleep(Duration::from_secs(RETRY_BACKOFF_SECS)); + } + continue; + } } else { + // streaming_download_and_extract already has its own internal retry loop streaming_download_and_extract( &archive.url, format, @@ -1553,6 +1572,13 @@ fn blocking_process_modular_archive( warn!(target: "reth::cli", file = %archive.file_name, component = %planned.component, attempt, "Extracted files failed integrity checks, retrying"); } + if let Some(e) = last_error { + return Err(e.wrap_err(format!( + "Failed after {} attempts for {}", + MAX_DOWNLOAD_RETRIES, archive.file_name + ))); + } + eyre::bail!( "Failed integrity validation after {} attempts for {}", MAX_DOWNLOAD_RETRIES,