tonhowtf/omniget · info

Send cancelled while waiting for receiver

Error message

Send cancelled while waiting for receiver

What it means

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.

Solutions

  1. No fix needed — handle it as expected cancellation in the caller and mark the session cancelled.
  2. If it fires unexpectedly, trace which component cancels the token (UI timeout, drop of session handle).
  3. Ensure the relay connection/socket is closed on cancellation so the receiver side doesn't hang.

Example fix

// before
run_sender(session).await?; // generic error surfaced to user
// after
if let Err(e) = run_sender(session).await {
    if e.to_string().contains("Send cancelled") {
        session.status.lock().await = "cancelled".into();
    } else { return Err(e); }
}
Defensive patterns

Strategy: try-catch

Validate before calling

if cancel.is_cancelled() { anyhow::bail!("Already cancelled before starting send"); }

Try / catch

match run_sender(session.clone(), cancel.clone()).await {
    Err(e) if e.to_string().contains("cancelled while waiting") => {
        session.status.lock().await = "cancelled".into();
    }
    other => other?,
}

Prevention

When it happens

Trigger: 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).

Common situations: User aborts a share before anyone enters the pairing code; the UI times out the session and cancels; app teardown cancels all sessions.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/e6841d4bdcfd6dac. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/src/platforms/p2p/mod.rs:275

    write_half
        .write_all(format!("SEND {}\n", session.code).as_bytes())
        .await?;
    write_half.flush().await?;

    let response = read_line(&mut reader).await?;
    check_relay_error(&response)?;
    if response != "WAIT" {
        anyhow::bail!("Unexpected relay response: {}", response);
    }

    *session.status.lock().await = "waiting_for_receiver".to_string();
    tracing::info!("[p2p] waiting for receiver... code: {}", session.code);

    let ready = tokio::select! {
        line = read_line(&mut reader) => line?,
        _ = cancel.cancelled() => {
            anyhow::bail!("Send cancelled while waiting for receiver");
        }
    };

    check_relay_error(&ready)?;
    if ready != "READY" {
        anyhow::bail!("Unexpected relay response: {}", ready);
    }

    *session.status.lock().await = "connected".to_string();
    tracing::info!("[p2p] receiver connected");

    let header = format!("{}\n{}\n", session.file_name, session.file_size);
    write_half.write_all(header.as_bytes()).await?;
    write_half.flush().await?;

    let ok_response = tokio::select! {
        line = read_line(&mut reader) => line?,
        _ = cancel.cancelled() => {

View on GitHub (pinned to 8600b91f42)