{"record":{"id":"e9895c20af87ac4c","repo":"nautechsystems/nautilus_trader","slug":"std-mem-take-mut-self-shutdown-errors-join-e9895c","errorCode":null,"errorMessage":"std::mem::take(&mut self.shutdown_errors).join(\"; \")","messagePattern":"std::mem::take\\(&mut self\\.shutdown_errors\\)\\.join\\(\"; \"\\)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/dydx/src/data.rs","lineNumber":299,"sourceCode":"        Ok(())\n    }\n\n    async fn finish_shutdown(&mut self) -> anyhow::Result<()> {\n        if let Err(e) = self\n            .ws_client\n            .disconnect()\n            .await\n            .context(\"failed to disconnect dYdX websocket\")\n        {\n            self.shutdown_errors.push(e.to_string());\n        }\n\n        if let Err(e) = self.finish_tasks().await {\n            self.shutdown_errors.push(e.to_string());\n        }\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    async fn teardown_partial_connect(&mut self) -> anyhow::Result<()> {\n        self.session_tasks.begin_shutdown();\n        self.command_tasks.begin_shutdown();\n        self.ws_client.begin_shutdown();\n        let shutdown_result = self.finish_shutdown().await;\n        self.is_connected.store(false, Ordering::Release);\n        shutdown_result\n    }\n\n    async fn bootstrap_instruments(&self) -> anyhow::Result<Vec<InstrumentAny>> {\n        self.http_client\n            .fetch_and_cache_instruments()\n            .await\n            .context(\"failed to load instruments from dYdX\")?;","sourceCodeStart":281,"sourceCodeEnd":317,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/dydx/src/data.rs#L281-L317","documentation":"The dYdX data client aggregates all errors encountered while shutting down its background tasks into self.shutdown_errors; finish_shutdown drains that vec and bails with the messages joined by '; ' so no failure detail is lost. This surfaces any task that failed or panicked during teardown.","triggerScenarios":"Calling finish_shutdown (via prepare_task_groups or teardown_partial_connect) when one or more session/finish tasks returned Err or panicked, after finish_tasks collected their error strings.","commonSituations":"WebSocket connections failing with network errors mid-teardown; a send task erroring while the client is being stopped; partial-connect cleanup after an auth failure.","solutions":["Read the joined message to identify each underlying task error and fix the root cause","Check network/proxy stability if errors are WebSocket-related","Log shutdown errors at teardown and treat transient ones as non-fatal in the calling strategy"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match client.disconnect().await {\n    Ok(()) => {},\n    Err(e) => {\n        // e contains all task shutdown errors joined by '; '\n        for msg in e.to_string().split(\"; \") {\n            log::warn!(\"shutdown task error: {msg}\");\n        }\n    }\n}","preventionTips":["Monitor WebSocket health during the session so failures surface before shutdown","Treat transient network errors during teardown as non-fatal and log them"],"tags":["rust","dydx-exchange","shutdown","task-error"],"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"}