{"record":{"id":"6cf5e0daea637e7d","repo":"tonhowtf/omniget","slug":"download-cancelled-6cf5e0","errorCode":null,"errorMessage":"Download cancelled","messagePattern":"Download cancelled","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"src-tauri/src/platforms/magnet/mod.rs","lineNumber":266,"sourceCode":"                            \"[magnet] progress: {:.1}% ({:.1} MB / {:.1} MB)\",\n                            pct,\n                            downloaded as f64 / 1_048_576.0,\n                            total as f64 / 1_048_576.0,\n                        );\n                        // Fallback: detect completion from stats when\n                        // wait_until_completed() doesn't resolve\n                        if downloaded >= total {\n                            tracing::info!(\"[magnet] download complete from stats (id={})\", torrent_id);\n                            break;\n                        }\n                    }\n                }\n                _ = cancel_rx.cancelled() => {\n                    tracing::info!(\"[magnet] download cancelled, removing torrent id={}\", torrent_id);\n                    if let Err(e) = session_for_cancel.delete(TorrentIdOrHash::Id(torrent_id), false).await {\n                        tracing::warn!(\"[magnet] failed to delete torrent on cancel: {}\", e);\n                    }\n                    anyhow::bail!(\"Download cancelled\");\n                }\n                res = &mut completion => {\n                    if let Err(e) = res {\n                        anyhow::bail!(\"Torrent download failed: {}\", e);\n                    }\n                    let _ = progress.send(ProgressUpdate::percent(100.0)).await;\n                    tracing::info!(\"[magnet] download complete (id={})\", torrent_id);\n                    break;\n                }\n            }\n        }\n\n        let (total_size, torrent_name) = managed_torrent\n            .with_metadata(|meta| {\n                let size = meta\n                    .info\n                    .iter_file_lengths()\n                    .ok()","sourceCodeStart":248,"sourceCodeEnd":284,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/src/platforms/magnet/mod.rs#L248-L284","documentation":"In the completion loop, the cancellation token fired before the torrent finished. The code deletes the torrent from the session (best-effort) and then bails with this error to unwind the download. This is the deliberate user-abort path, not a malfunction.","triggerScenarios":"cancel_rx.cancelled() resolves during the select! while the torrent download is in progress — user pressed stop, UI closed the task, or the app shut down.","commonSituations":"User cancels a slow torrent (few seeds); app exit while download running; a supervisor timeout cancelling long downloads.","solutions":["Treat this error as a normal cancellation in the caller (match on message or use a typed cancel error)","No remediation needed for the torrent — the code already deletes it from the session","If unexpected, audit who owns the CancellationToken and whether it is cancelled too early"],"exampleFix":"// before\nlet res = downloader.download(...).await?;\n// after\nlet res = match downloader.download(...).await {\n    Err(e) if format!(\"{e:#}\").contains(\"Download cancelled\") => return Ok(Cancelled),\n    other => other?,\n};","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match download(...).await {\n    Err(e) if format!(\"{e:#}\").contains(\"Download cancelled\") => info!(\"cancelled by user\"),\n    other => other?,\n}","preventionTips":["Model cancellation with a dedicated error type, not string matching","Scope the CancellationToken to a single download task"],"tags":["cancellation","torrent","async"],"backgroundTag":"invalid-state-transition","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}