{"record":{"id":"e6841d4bdcfd6dac","repo":"tonhowtf/omniget","slug":"send-cancelled-while-waiting-for-receiver-mod","errorCode":null,"errorMessage":"Send cancelled while waiting for receiver","messagePattern":"Send cancelled while waiting for receiver","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"src-tauri/src/platforms/p2p/mod.rs","lineNumber":275,"sourceCode":"\n    write_half\n        .write_all(format!(\"SEND {}\\n\", session.code).as_bytes())\n        .await?;\n    write_half.flush().await?;\n\n    let response = read_line(&mut reader).await?;\n    check_relay_error(&response)?;\n    if response != \"WAIT\" {\n        anyhow::bail!(\"Unexpected relay response: {}\", response);\n    }\n\n    *session.status.lock().await = \"waiting_for_receiver\".to_string();\n    tracing::info!(\"[p2p] waiting for receiver... code: {}\", session.code);\n\n    let ready = tokio::select! {\n        line = read_line(&mut reader) => line?,\n        _ = cancel.cancelled() => {\n            anyhow::bail!(\"Send cancelled while waiting for receiver\");\n        }\n    };\n\n    check_relay_error(&ready)?;\n    if ready != \"READY\" {\n        anyhow::bail!(\"Unexpected relay response: {}\", ready);\n    }\n\n    *session.status.lock().await = \"connected\".to_string();\n    tracing::info!(\"[p2p] receiver connected\");\n\n    let header = format!(\"{}\\n{}\\n\", session.file_name, session.file_size);\n    write_half.write_all(header.as_bytes()).await?;\n    write_half.flush().await?;\n\n    let ok_response = tokio::select! {\n        line = read_line(&mut reader) => line?,\n        _ = cancel.cancelled() => {","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/src/platforms/p2p/mod.rs#L257-L293","documentation":"While the sender waits for the receiver's READY line, tokio::select! races read_line against cancel.cancelled(). If the CancellationToken fires first, run_sender bails with \"Send cancelled while waiting for receiver\". Expected cooperative cancellation, not a protocol failure.","triggerScenarios":"Calling cancel_token.cancel() on the send session while it is parked in the waiting_for_receiver state (after receiving WAIT from the relay, before READY arrives).","commonSituations":"User aborts a share before anyone enters the pairing code; the UI times out the session and cancels; app teardown cancels all sessions.","solutions":["No fix needed — handle it as expected cancellation in the caller and mark the session cancelled.","If it fires unexpectedly, trace which component cancels the token (UI timeout, drop of session handle).","Ensure the relay connection/socket is closed on cancellation so the receiver side doesn't hang."],"exampleFix":"// before\nrun_sender(session).await?; // generic error surfaced to user\n// after\nif let Err(e) = run_sender(session).await {\n    if e.to_string().contains(\"Send cancelled\") {\n        session.status.lock().await = \"cancelled\".into();\n    } else { return Err(e); }\n}","handlingStrategy":"try-catch","validationCode":"if cancel.is_cancelled() { anyhow::bail!(\"Already cancelled before starting send\"); }","typeGuard":null,"tryCatchPattern":"match run_sender(session.clone(), cancel.clone()).await {\n    Err(e) if e.to_string().contains(\"cancelled while waiting\") => {\n        session.status.lock().await = \"cancelled\".into();\n    }\n    other => other?,\n}","preventionTips":["Cancel only from explicit user action or a clearly-logged session timeout.","Give each send session its own CancellationToken; never share across sessions.","Update session status before cancelling so the UI state is consistent.","Drop the session handle after cancelling to free the relay slot."],"tags":["cancellation","p2p","send","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"}