{"record":{"id":"a4598ce7af6b0b10","repo":"xai-org/grok-build","slug":"connection-cancelled","errorCode":null,"errorMessage":"Connection cancelled","messagePattern":"Connection cancelled","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"crates/codegen/xai-grok-shell/src/agent/relay.rs","lineNumber":415,"sourceCode":"    );\n    Ok(req)\n}\n/// Attempt to connect to the relay WebSocket server.\n///\n/// If `proxy_url` is `Some`, the connection is established through an HTTP\n/// CONNECT tunnel.  Otherwise, a direct connection is used.\nasync fn connect_to_relay(\n    config: &RelayConfig,\n    proxy_url: Option<&str>,\n    cancel: &CancellationToken,\n) -> anyhow::Result<\n    tokio_tungstenite::WebSocketStream<tokio_tungstenite::MaybeTlsStream<tokio::net::TcpStream>>,\n> {\n    let req = build_relay_request(config)?;\n    let connect_timeout = Duration::from_secs(CONNECT_TIMEOUT_SECS);\n    tokio::select! {\n        _ = cancel.cancelled() => {\n            anyhow::bail!(\"Connection cancelled\");\n        }\n        result = tokio::time::timeout(connect_timeout, async {\n            if let Some(proxy_url) = proxy_url {\n                // Proxy path: open TCP to proxy, send CONNECT, then WS handshake.\n                let target_host = req.uri().host()\n                    .ok_or_else(|| anyhow::anyhow!(\"WebSocket URL has no host\"))?;\n                let target_port = req.uri().port_u16().unwrap_or(443);\n                let tunneled_stream = proxy::connect_via_proxy(\n                    proxy_url,\n                    target_host,\n                    target_port,\n                ).await?;\n                // Perform the WebSocket handshake over the tunneled stream.\n                let (ws, resp) = tokio_tungstenite::client_async(req, tunneled_stream)\n                    .await\n                    .map_err(|e| anyhow::Error::from(e).context(\"WebSocket handshake via proxy failed\"))?;\n                Ok((ws, resp))\n            } else {","sourceCodeStart":397,"sourceCodeEnd":433,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-shell/src/agent/relay.rs#L397-L433","documentation":"connect_to_relay races the WebSocket connection attempt against a cancellation token via tokio::select!. If the cancellation token fires before the connection completes, the function bails with \"Connection cancelled\" instead of continuing to connect.","triggerScenarios":"The cancel token (passed into connect_to_relay from run_relay_loop) is cancelled during the CONNECT_TIMEOUT_SECS-bounded connection attempt — typically shutdown, reconnect-with-new-session, or user abort racing the handshake.","commonSituations":"User interrupts the agent while it is dialing the relay; the relay loop initiates a reconnect and cancels the in-flight old connection; application shutdown during slow network startup.","solutions":["Treat this as an expected cooperative-cancel signal — check whether shutdown/reconnect was intended.","If it fires unexpectedly, audit what triggers the cancellation token (e.g. run_relay_loop restart logic).","Retry the connection if cancellation was spurious and the session should persist."],"exampleFix":"// before\nlet ws = connect_to_relay(&config, &cancel, proxy_url).await?;\n// after\nmatch connect_to_relay(&config, &cancel, proxy_url).await {\n    Ok(ws) => ws,\n    Err(e) if e.to_string() == \"Connection cancelled\" => return Ok(()), // graceful shutdown\n    Err(e) => return Err(e),\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match connect_to_relay(&config, &cancel, proxy).await {\n    Err(e) if e.to_string() == \"Connection cancelled\" => {\n        // expected during shutdown/reconnect — exit cleanly, don't log as error\n        return Ok(());\n    }\n    Err(e) => return Err(e),\n    Ok(ws) => use_ws(ws),\n}","preventionTips":["Treat this message as a cooperative-cancel signal, not a failure","Avoid cancelling the token spuriously during startup; only cancel on real shutdown/reconnect","Pattern-match the exact message when distinguishing cancel from real connection errors"],"tags":["websocket","cancellation","async","tokio","relay"],"backgroundTag":"operation-cancelled","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}