{"record":{"id":"3248bb6b3a97543d","repo":"tonhowtf/omniget","slug":"send-cancelled-while-paused-mod","errorCode":null,"errorMessage":"Send cancelled while paused","messagePattern":"Send cancelled while paused","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"src-tauri/src/platforms/p2p/mod.rs","lineNumber":321,"sourceCode":"    tracing::info!(\n        \"[p2p] transferring: {} ({} bytes)\",\n        session.file_name,\n        session.file_size\n    );\n\n    let mut file = File::open(&session.file_path).await?;\n    let mut buf = vec![0u8; CHUNK_SIZE];\n    let mut sent: u64 = 0;\n\n    loop {\n        if cancel.is_cancelled() {\n            anyhow::bail!(\"Send cancelled during transfer\");\n        }\n\n        while session.paused.load(std::sync::atomic::Ordering::Relaxed) {\n            tokio::time::sleep(std::time::Duration::from_millis(100)).await;\n            if cancel.is_cancelled() {\n                anyhow::bail!(\"Send cancelled while paused\");\n            }\n        }\n\n        let n = file.read(&mut buf).await?;\n        if n == 0 {\n            break;\n        }\n\n        write_half.write_all(&buf[..n]).await?;\n        sent += n as u64;\n\n        *session.sent_bytes.lock().await = sent;\n        if session.file_size > 0 {\n            *session.progress.lock().await = (sent as f64 / session.file_size as f64) * 100.0;\n        }\n    }\n\n    write_half.flush().await?;","sourceCodeStart":303,"sourceCodeEnd":339,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/src/platforms/p2p/mod.rs#L303-L339","documentation":"While the session is paused (session.paused is true), run_sender sleeps in 100ms intervals and re-checks cancel each tick; if the token fires during the pause, it bails with \"Send cancelled while paused\". Distinguishes cancellation-while-paused from cancellation-during-transfer for clearer UI state.","triggerScenarios":"User pauses the transfer (setting session.paused) and then cancels; the next 100ms poll observes is_cancelled() inside the pause spin-loop.","commonSituations":"User pauses, changes their mind, and hits cancel; UI cancels long-paused sessions after a timeout; app shutdown while a transfer sits paused.","solutions":["Expected control flow — handle it as a cancellation and clear both paused and cancel state on the session.","If surprising, check whether the UI auto-cancels sessions paused beyond a threshold.","On catch, close the relay connection so the blocked receiver doesn't wait forever."],"exampleFix":"// before\n// cancel during pause reported as generic failure\nif let Err(e) = run_sender(session).await { return Err(e); }\n// after\nif let Err(e) = run_sender(session).await {\n    if e.to_string().contains(\"cancelled while paused\") {\n        session.paused.store(false, std::sync::atomic::Ordering::Relaxed);\n        ui.mark_cancelled(&session.id);\n    } else { return Err(e); }\n}","handlingStrategy":"try-catch","validationCode":"if cancel.is_cancelled() && session.paused.load(std::sync::atomic::Ordering::Relaxed) {\n    anyhow::bail!(\"Cannot pause: session already cancelled\");\n}","typeGuard":null,"tryCatchPattern":"match run_sender(session.clone(), cancel.clone()).await {\n    Err(e) if e.to_string().contains(\"cancelled while paused\") => {\n        session.paused.store(false, std::sync::atomic::Ordering::Relaxed);\n        session.status.lock().await = \"cancelled\".into();\n    }\n    other => other?,\n}","preventionTips":["Auto-cancel only paused sessions after a user-visible timeout.","Clear the paused flag whenever the session is cancelled or dropped.","Distinguish pause/cancel buttons clearly in the UI to avoid accidental cancels.","Close the relay socket on cancel so the receiver doesn't hang on its read."],"tags":["cancellation","p2p","pause","control-flow"],"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"}