{"record":{"id":"c0b2476012977b4f","repo":"Zackriya-Solutions/meetily","slug":"download-cancelled-by-user","errorCode":null,"errorMessage":"Download cancelled by user","messagePattern":"Download cancelled by user","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"frontend/src-tauri/src/parakeet_engine/parakeet_engine.rs","lineNumber":841,"sourceCode":"\n            // Stream download\n            use futures_util::StreamExt;\n            let mut stream = response.bytes_stream();\n            let mut file_downloaded = if resuming { existing_size } else { 0u64 };\n\n            loop {\n                // Check for cancellation before processing chunk\n                {\n                    let cancel_flag = self.cancel_download_flag.read().await;\n                    if cancel_flag.as_ref() == Some(&model_name.to_string()) {\n                        log::info!(\"Download cancelled for {}\", model_name);\n                        // Flush and keep partial file for resume on next attempt\n                        let _ = writer.flush().await;\n                        drop(writer);\n                        // Remove from active downloads on cancellation\n                        let mut active = self.active_downloads.write().await;\n                        active.remove(model_name);\n                        return Err(anyhow!(\"Download cancelled by user\"));\n                    }\n                }\n\n                // Add per-chunk timeout (30 seconds) to detect stalled connections\n                let next_result = timeout(Duration::from_secs(30), stream.next()).await;\n\n                let chunk = match next_result {\n                    // Timeout - no data received for 30 seconds\n                    Err(_) => {\n                        log::warn!(\"Download timeout for {}: no data received for 30 seconds\", model_name);\n                        let _ = writer.flush().await;\n\n                        // Remove from active downloads\n                        {\n                            let mut active = self.active_downloads.write().await;\n                            active.remove(model_name);\n                        }\n","sourceCodeStart":823,"sourceCodeEnd":859,"githubUrl":"https://github.com/Zackriya-Solutions/meetily/blob/0281737d87d26352fb0adc78c8c0975f691b23d1/frontend/src-tauri/src/parakeet_engine/parakeet_engine.rs#L823-L859","documentation":"Returned when the engine's cancel_download_flag is set to the model currently being downloaded. This is deliberate control flow, not a malfunction: the writer is flushed, the partial file is intentionally kept on disk for a future resume, and the model is removed from the active downloads set.","triggerScenarios":"Invoking the cancel-download flag/command while download is streaming chunks for that same model name; any task that sets cancel_download_flag to Some(model_name) while the download loop is between chunks.","commonSituations":"User clicks Cancel in the downloads UI; a settings screen cancels a pending fetch when switching engines; tests abort long downloads by setting the flag.","solutions":["Map this error to a 'Cancelled' UI state in the caller — do not show it as a failure dialog","Do not auto-retry a cancelled download; wait for the user to explicitly request it again","Rely on the preserved partial file so the next attempt resumes instead of restarting from zero"],"exampleFix":"// caller: treat cancellation as a normal outcome\nlet res = engine.download_model(\"parakeet-mlx-0.6b-v3\", None).await;\nmatch res {\n    Err(e) if e.to_string() == \"Download cancelled by user\" => {\n        ui.set_state(DownloadState::Cancelled); // keep partial file for resume\n    }\n    Err(e) => ui.show_error(e),\n    Ok(()) => ui.set_state(DownloadState::Done),\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"let res = engine.download_model(name, cb).await;\nmatch res {\n    Err(e) if e.to_string() == \"Download cancelled by user\" => Ok(Outcome::Cancelled), // not an error\n    r => r.map(|_| Outcome::Done),\n}","preventionTips":["Treat cancellation as a first-class UI state, distinct from failure","Disable the Cancel button once the flag is set to avoid double signals","Keep the partial file so the next attempt resumes instead of restarting"],"tags":["cancellation","download","async","rust"],"backgroundTag":"operation-cancelled","analyzedSha":"0281737d87d26352fb0adc78c8c0975f691b23d1","analyzedAt":"2026-08-16T20:57:52.567Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}