mirror of
https://github.com/zhom/donutbrowser.git
synced 2026-09-26 19:22:09 +02:00
refactor: better error handling for failed downloads
This commit is contained in:
@@ -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
@@ -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());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user