refactor: better error handling for failed downloads

This commit is contained in:
zhom
2025-08-16 11:50:34 +04:00
parent c98e12900f
commit 96c42ae55e
3 changed files with 43 additions and 52 deletions
+4 -3
View File
@@ -1380,9 +1380,10 @@ impl BrowserRunner {
return Err(error_details.into()); return Err(error_details.into());
} }
registry // Mark completion in registry. If it fails (e.g., rare race during cleanup), log but continue.
.mark_download_completed(&browser_str, &version) if let Err(e) = registry.mark_download_completed(&browser_str, &version) {
.map_err(|e| format!("Failed to mark download as completed: {e}"))?; eprintln!("Warning: Could not mark {browser_str} {version} as completed in registry: {e}");
}
registry registry
.save() .save()
.map_err(|e| format!("Failed to save registry: {e}"))?; .map_err(|e| format!("Failed to save registry: {e}"))?;
+35 -14
View File
@@ -402,23 +402,44 @@ impl Downloader {
existing_size = meta.len(); existing_size = meta.len();
} }
// Build request, add Range only if we have bytes // Build request, add Range only if we have bytes. If the server responds with 416 (Range Not
let mut request = self // Satisfiable), delete the partial file and retry once without the Range header.
.client let response = {
.get(&download_url) let mut request = self
.header( .client
"User-Agent", .get(&download_url)
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36", .header(
); "User-Agent",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36",
);
if existing_size > 0 { if existing_size > 0 {
request = request.header("Range", format!("bytes={existing_size}-")); request = request.header("Range", format!("bytes={existing_size}-"));
} }
// Start download (or resume) let first = request.send().await?;
let response = request.send().await?;
// Check if the response is successful if first.status().as_u16() == 416 && existing_size > 0 {
// Partial file on disk is not acceptable to the server — remove it and retry from scratch
let _ = std::fs::remove_file(&file_path);
existing_size = 0;
let retry = self
.client
.get(&download_url)
.header(
"User-Agent",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36",
)
.send()
.await?;
retry
} else {
first
}
};
// Check if the response is successful (200 OK or 206 Partial Content)
if !(response.status().is_success() || response.status().as_u16() == 206) { if !(response.status().is_success() || response.status().as_u16() == 206) {
return Err(format!("Download failed with status: {}", response.status()).into()); return Err(format!("Download failed with status: {}", response.status()).into());
} }
+4 -35
View File
@@ -727,41 +727,10 @@ pub mod windows {
cmd.current_dir(parent_dir); cmd.current_dir(parent_dir);
} }
let output = cmd.output()?; // Do not call output() to avoid blocking the UI thread while the browser processes the request.
// Spawn the helper process and return immediately. This applies to Chromium-based browsers
if !output.status.success() { // including Brave to prevent UI freezes observed in production.
// Try fallback without --new-window let _child = cmd.spawn()?;
let mut fallback_cmd = Command::new(&executable_path);
fallback_cmd.args([
&format!(
"--user-data-dir={}",
profile
.get_profile_data_path(profiles_dir)
.to_string_lossy()
),
url,
]);
if let Some(parent_dir) = browser_dir
.parent()
.or_else(|| browser_dir.ancestors().nth(1))
{
fallback_cmd.current_dir(parent_dir);
}
let fallback_output = fallback_cmd.output()?;
if !fallback_output.status.success() {
return Err(
format!(
"Failed to open URL in existing Chromium-based browser: {}",
String::from_utf8_lossy(&fallback_output.stderr)
)
.into(),
);
}
}
Ok(()) Ok(())
} }