{"record":{"id":"34ea590f8c4c3130","repo":"nautechsystems/nautilus_trader","slug":"std-mem-take-mut-self-shutdown-errors-join-34ea59","errorCode":null,"errorMessage":"std::mem::take(&mut self.shutdown_errors).join(\"; \")","messagePattern":"std::mem::take\\(&mut self\\.shutdown_errors\\)\\.join\\(\"; \"\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/coinbase/src/data/mod.rs","lineNumber":334,"sourceCode":"\n        let (tasks_result, polls_result) =\n            tokio::join!(self.finish_tasks(), self.deriv_polls.finish_shutdown());\n\n        if let Err(e) = tasks_result {\n            self.shutdown_errors.push(e.to_string());\n        }\n\n        if let Err(e) = polls_result {\n            self.shutdown_errors.push(e.to_string());\n        }\n\n        if let Err(e) = self.ws_client.disconnect().await {\n            self.shutdown_errors.push(e.to_string());\n        }\n        self.is_connected.store(false, Ordering::Relaxed);\n\n        if !self.shutdown_errors.is_empty() {\n            anyhow::bail!(std::mem::take(&mut self.shutdown_errors).join(\"; \"));\n        }\n        Ok(())\n    }\n\n    fn product_id(instrument_id: InstrumentId) -> Ustr {\n        instrument_id.symbol.inner()\n    }\n\n    // Resolves a caller-supplied product id to Coinbase's canonical alias (if\n    // any). Coinbase consolidates aliased pairs into a single book server-side\n    // and rewrites WS subscription confirmations and inbound messages to use\n    // the canonical id (e.g. BTC-USDC -> BTC-USD), so we must subscribe with\n    // the canonical id and remember the mapping so inbound messages can be\n    // re-keyed to what the strategy actually subscribed to.\n    fn resolve_wire_product_id(&self, subscribed: Ustr) -> Ustr {\n        self.http_client\n            .product_aliases()\n            .get_cloned(&subscribed)","sourceCodeStart":316,"sourceCodeEnd":352,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/coinbase/src/data/mod.rs#L316-L352","documentation":"teardown_partial_connect on the Coinbase data client accumulates any errors encountered while disconnecting the WebSocket (and other partial-connect teardown steps) into shutdown_errors, then fails the teardown with all messages joined by '; '. This surfaces why a partially-connected client could not be cleanly rolled back.","triggerScenarios":"A connect() step fails partway and the rollback path calls ws_client.disconnect().await which itself errors (e.g. socket already closed, network gone), leaving non-empty shutdown_errors.","commonSituations":"Network drop during a failed connect; calling disconnect() on a client whose WS is already dead; concurrent teardowns racing on the same client.","solutions":["Read the joined message to identify which teardown step(s) failed (usually the WS disconnect)","Retry disconnect() once after a short delay; the socket may already be half-closed","Recreate the client if teardown repeatedly fails — state may be inconsistent after partial connect","Fix the root cause of the original partial connect that triggered the rollback"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// ensure the client is connected before disconnect\nif client.is_connected() { client.disconnect().await?; }","typeGuard":null,"tryCatchPattern":"if let Err(e) = client.disconnect().await {\n    log::warn!(\"coinbase teardown failed: {e}; recreating client\");\n    client = rebuild_client().await;\n}","preventionTips":["Fix the root connect failure so the rollback path is rarely taken","Recreate clients after any teardown error instead of reusing them","Log full teardown messages — they are '; '-joined multi-error strings","Avoid concurrent disconnect calls on the same client"],"tags":["teardown","websocket","rust","cleanup"],"backgroundTag":"http-request-failed","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}