{"record":{"id":"982452c1762a1e3a","repo":"tonhowtf/omniget","slug":"send-cancelled-during-transfer","errorCode":null,"errorMessage":"Send cancelled during transfer","messagePattern":"Send cancelled during transfer","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"src-tauri/omniget-core/src/platforms/p2p.rs","lineNumber":313,"sourceCode":"\n    if ok_response != \"OK\" {\n        anyhow::bail!(\"Receiver rejected transfer: {}\", ok_response);\n    }\n\n    *session.status.lock().await = \"transferring\".to_string();\n    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;","sourceCodeStart":295,"sourceCodeEnd":331,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/platforms/p2p.rs#L295-L331","documentation":"During the byte-transfer loop in run_sender, the cancel token is polled every iteration; if it fires, the send aborts with this error. Like the other cancellation errors, it signals a deliberate abort (including cancel-during-pause) rather than a transport failure. The receiver will see the connection drop mid-stream.","triggerScenarios":"Cancelling the CancellationToken while run_sender is actively writing file bytes (or while it is parked in the paused busy-wait loop — that path raises \"Send cancelled while paused\" from the same phase).","commonSituations":"User stops a large mid-flight transfer; app shutdown during a long send; a supervisor cancels stalled or paused sessions.","solutions":["Treat as a user-intended abort: match on the message and mark the session cancelled rather than failed","For resumable sends, record the bytes-sent offset before cancelling and implement range-resume on a new session","Always drain/notify so the receiver's partial file can be cleaned up (mirror the receiver's remove_file behavior)"],"exampleFix":"// before\nif cancel.is_cancelled() {\n    anyhow::bail!(\"Send cancelled during transfer\");\n}\n// after\nif cancel.is_cancelled() {\n    *session.status.lock().await = \"cancelled\".to_string();\n    tracing::info!(\"[p2p] cancelled after {} of {} bytes\", sent, session.file_size);\n    anyhow::bail!(\"Send cancelled during transfer\");\n}","handlingStrategy":"try-catch","validationCode":"// Only cancel mid-transfer for explicit user stop\nif cancel.is_cancelled() {\n    anyhow::bail!(\"Not starting transfer: token already cancelled\");\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = run_sender(&mut session, &cancel).await {\n    if e.to_string().contains(\"Send cancelled\") {\n        session.status.lock().await = \"cancelled\".into();\n        tracing::info!(\"[p2p] send aborted by user\");\n    } else {\n        return Err(e);\n    }\n}","preventionTips":["Persist sent-byte offsets so cancelled transfers can resume later","Avoid long paused states; auto-cancel paused sessions after a timeout","Coordinate receiver-side cleanup for partial files when the sender aborts"],"tags":["p2p","cancellation","sender","transfer"],"backgroundTag":"operation-cancelled","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"}