{"record":{"id":"ec810fbd65ac64cc","repo":"nautechsystems/nautilus_trader","slug":"shutdown-errors-joined-with","errorCode":null,"errorMessage":"{shutdown_errors joined with \"; \"}","messagePattern":"\\{shutdown_errors joined with \"; \"\\}","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/hyperliquid/src/data.rs","lineNumber":250,"sourceCode":"        self.abort_pending_tasks();\n\n        if let Err(e) = self.ws_client.disconnect().await {\n            self.shutdown_errors\n                .push(format!(\"Hyperliquid WebSocket shutdown failed: {e}\"));\n        }\n\n        if let Err(e) = self.await_session_tasks().await {\n            self.shutdown_errors.push(e.to_string());\n        }\n\n        if let Err(e) = self.await_pending_tasks().await {\n            self.shutdown_errors.push(e.to_string());\n        }\n        self.clear_stream_health();\n        self.is_connected.store(false, Ordering::Release);\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 await_pending_tasks(&self) -> anyhow::Result<()> {\n        self.pending_tasks.begin_shutdown();\n        self.pending_tasks\n            .finish_shutdown(Duration::from_secs(1), Duration::from_secs(2))\n            .await\n            .map_err(|e| anyhow::anyhow!(\"Failed to terminate Hyperliquid data tasks: {e}\"))?;\n        Ok(())\n    }\n\n    async fn await_session_tasks(&self) -> anyhow::Result<()> {\n        self.session_tasks.begin_shutdown();\n        self.session_tasks\n            .finish_shutdown(Duration::from_secs(1), Duration::from_secs(2))\n            .await","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/hyperliquid/src/data.rs#L232-L268","documentation":"During HyperliquidDataClient teardown (teardown_partial_connect), any errors from shutting down individual streams/tasks are accumulated in shutdown_errors. If any were collected, teardown fails and the joined messages are surfaced as a single bail! describing every component-level shutdown problem encountered.","triggerScenarios":"Calling connect() or disconnect() when one or more underlying WebSocket streams or spawned tasks fail to shut down cleanly — e.g. a ws client close errors, a task join fails, or clear/register stream health cleanup errors during teardown.","commonSituations":"Network interruptions at disconnect time; attempting to connect after a previous partial failure left stale resources; abrupt venue-side disconnections causing task panics that surface during teardown.","solutions":["Read the joined messages to identify the failing component, then fix the root cause (e.g. network reachability of Hyperliquid WS endpoints).","Retry the connect/disconnect operation after ensuring no stale client state; reconnect cleanly.","Check logs for the individual per-component errors that were pushed into shutdown_errors during teardown."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match client.connect().await {\n    Err(e) if e.to_string().contains(';') => {\n        tracing::warn!(\"partial shutdown errors: {e}\");\n        // inspect per-component logs, then retry connect\n    }\n    r => r?,\n}","preventionTips":["Ensure clean network reachability to Hyperliquid WS endpoints before connect.","Fully disconnect clients before reconnecting to avoid stale tasks.","Monitor logs for per-component teardown errors that aggregate here."],"tags":["teardown","websockets","data-client","hyperliquid"],"backgroundTag":"network-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"}