fix: resolve deadlock, redownload failure, and UI issues

- Fix re-entrant deadlock in `legacy_download_queue_paths` by scoping DB lock
- Ensure `release_registered_id` runs in `remove_download` even if cleanup fails
- Add fallback to `std::fs::remove_file` if `trash::delete` fails
- Ignore 'cannot be paused now' error in `detach_download_for_reconfigure`
- Apply `break-all` and `whitespace-pre-wrap` to Toast messages to prevent UI overflow
This commit is contained in:
NimBold
2026-06-25 14:27:38 +03:30
parent b4ff14805b
commit 069c1b6788
3 changed files with 35 additions and 18 deletions
+25 -10
View File
@@ -2869,15 +2869,19 @@ async fn remove_download(
crate::ipc::DownloadStateEvent::new(id.clone(), crate::ipc::DownloadStatus::Paused),
);
if delete_assets {
if let Some(path) = primary_path.as_deref() {
remove_download_assets(path, &app_handle).await?;
let cleanup_result = (|| async {
if delete_assets {
if let Some(path) = primary_path.as_deref() {
remove_download_assets(path, &app_handle).await?;
}
}
}
crate::download_ownership::remove(&app_handle, &id)?;
Ok::<(), String>(())
})()
.await;
crate::download_ownership::remove(&app_handle, &id)?;
state.queue_manager.release_registered_id(&id).await;
Ok(())
cleanup_result
}
async fn remove_download_assets(
@@ -2889,8 +2893,12 @@ async fn remove_download_assets(
}
if primary.exists() {
trash::delete(primary)
.map_err(|error| format!("failed to move downloaded file to Trash: {error}"))?;
if let Err(e) = trash::delete(primary) {
log::warn!("failed to move downloaded file to Trash, attempting hard delete: {}", e);
if let Err(hard_err) = std::fs::remove_file(primary) {
return Err(format!("failed to move downloaded file to Trash ({e}) and hard delete failed ({hard_err})"));
}
}
}
for suffix in [".aria2", ".part", ".ytdl"] {
@@ -2923,13 +2931,20 @@ async fn detach_download_for_reconfigure(
if let Some(gid) = gid.as_deref().filter(|gid| !gid.starts_with("native:")) {
let removal_result = async {
rpc_call(
let pause_res = rpc_call(
state.aria2_port.load(std::sync::atomic::Ordering::Relaxed),
&state.aria2_secret,
"aria2.forcePause",
serde_json::json!([gid]),
)
.await?;
.await;
if let Err(e) = pause_res {
if !e.contains("cannot be paused now") {
return Err(e);
}
}
wait_for_aria2_stopped(
state.aria2_port.load(std::sync::atomic::Ordering::Relaxed),
&state.aria2_secret,