tonhowtf/omniget · info

Send cancelled while waiting for OK

Error message

Send cancelled while waiting for OK

What it means

After sending the file header (name + size) to the receiver, run_sender waits for an "OK" acknowledgement inside a tokio::select! against the cancel token. If cancellation fires while waiting, this error aborts the send. It's cooperative cancellation, distinct from a receiver rejection (which produces error 88).

Solutions

  1. Treat as an intentional abort: match the message and reset session status instead of logging a failure
  2. If you want graceful shutdown, notify the receiver/relay before cancelling so the half-negotiated session is cleaned up
  3. Restart with a fresh start_send session; the cancelled session cannot be resumed

Example fix

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

Strategy: try-catch

Validate before calling

// Don't cancel during negotiation unless the user explicitly aborts
debug_assert!(!cancel.is_cancelled(), "token must be live until transfer starts");

Try / catch

if let Err(e) = run_sender(&mut session, &cancel).await {
    if e.to_string().contains("cancelled") {
        session.status.lock().await = "cancelled".into();
    } else {
        return Err(e);
    }
}

Prevention

When it happens

Trigger: Cancelling the CancellationToken after run_sender wrote the file header but before the receiver's "OK" response arrives.

Common situations: User aborts the send at the confirmation screen; receiver is slow to approve and the user gives up; app shutdown cancels the pending negotiation.

Related errors


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

Appendix: source

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

        }
    };

    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() => {
            anyhow::bail!("Send cancelled while waiting for OK");
        }
    };

    if ok_response != "OK" {
        anyhow::bail!("Receiver rejected transfer: {}", ok_response);
    }

    *session.status.lock().await = "transferring".to_string();
    tracing::info!(
        "[p2p] transferring: {} ({} bytes)",
        session.file_name,
        session.file_size
    );

    let mut file = File::open(&session.file_path).await?;
    let mut buf = vec![0u8; CHUNK_SIZE];
    let mut sent: u64 = 0;

View on GitHub (pinned to 8600b91f42)