tonhowtf/omniget · info

Send cancelled while waiting for receiver

Error message

Send cancelled while waiting for receiver

What it means

run_sender waits for the relay's "READY" line inside a tokio::select! that races read_line against the cancel token. If cancellation wins, the library aborts with this explicit error instead of a generic one. It is deliberate cooperative cancellation during the wait-for-receiver phase, not a network failure.

Solutions

  1. Treat as a benign, user-initiated abort: match on the message and update session status without surfacing a scary error
  2. If auto-retry is desired, create a new cancel token and a fresh session (start_send) — do not reuse the cancelled one
  3. Always cancel cleanly so the relay slot is freed; consider notifying the relay/session teardown on abort

Example fix

// before
_ = cancel.cancelled() => {
    anyhow::bail!("Send cancelled while waiting for receiver");
}
// after
_ = cancel.cancelled() => {
    *session.status.lock().await = "cancelled".to_string();
    anyhow::bail!("Send cancelled while waiting for receiver");
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Only start a send with a live, non-cancelled token
if cancel.is_cancelled() {
    anyhow::bail!("Refusing to start send with a cancelled token");
}

Try / catch

let result = p2p::start_send(path).await;
match result {
    Ok(session) => { /* run_sender handles its own cancel errors */ }
    Err(e) if e.to_string().contains("cancelled") => { /* user aborted: update UI, no error */ }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Cancelling the CancellationToken passed to run_sender while the sender is still waiting for a receiver to connect (before any "READY" line arrives).

Common situations: User closes the send dialog while waiting; app shuts down; a UI-level timeout cancels long-idle sessions that never found a receiver.

Related errors


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

Appendix: source

Thrown at src-tauri/omniget-core/src/platforms/p2p.rs:273

    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)