{"record":{"id":"15099be29c0048c0","repo":"nautechsystems/nautilus_trader","slug":"errors-joined-with-aggregated-disconnect-err","errorCode":null,"errorMessage":"errors joined with \"; \" (aggregated disconnect errors)","messagePattern":"errors joined with \"; \" \\(aggregated disconnect errors\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/deribit/src/data.rs","lineNumber":263,"sourceCode":"        }\n\n        let mut errors = Vec::new();\n\n        if let Some(ws) = self.ws_client.as_ref()\n            && let Err(e) = ws.close().await\n        {\n            errors.push(format!(\"WebSocket shutdown failed: {e}\"));\n        }\n\n        if let Err(e) = self.finish_tasks().await {\n            errors.push(e.to_string());\n        }\n        self.is_connected.store(false, Ordering::Release);\n\n        if errors.is_empty() {\n            Ok(())\n        } else {\n            anyhow::bail!(errors.join(\"; \"))\n        }\n    }\n\n    /// Gets the interval from params, defaulting to Raw if authenticated.\n    ///\n    /// If authenticated, we prefer Raw interval for best data quality.\n    /// Users can still override via params if they want 100ms or agg2.\n    fn get_interval(&self, params: &Option<Params>) -> Option<DeribitUpdateInterval> {\n        if let Some(interval) = params\n            .as_ref()\n            .and_then(|p| p.get_str(\"interval\"))\n            .and_then(|s| s.parse::<DeribitUpdateInterval>().ok())\n        {\n            return Some(interval);\n        }\n\n        // Default to Raw if authenticated, otherwise None (100ms default)\n        if let Some(ws) = self.ws_client.as_ref()","sourceCodeStart":245,"sourceCodeEnd":281,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/deribit/src/data.rs#L245-L281","documentation":"During disconnect or a failed partial connect, the Deribit adapter tears down session and pending tokio tasks and collects any error each teardown step produced. Instead of failing on the first error, it aggregates all of them and returns a single anyhow error with the messages joined by \"; \". This means the connection teardown hit one or more problems (e.g. tasks failed to shut down cleanly, channel sends failed), all of which are reported at once.","triggerScenarios":"Calling client.disconnect(), or connect() when the WebSocket/HTTP setup partially fails, causes teardown_partial_connect to run; if any spawned task join or shutdown step errors, the errors vec is non-empty and bail!(errors.join(\"; \")) fires.","commonSituations":"Network drop mid-session so the WS task already died and shutdown signals fail; calling disconnect twice or disconnecting while tasks are stuck waiting on the remote; cancel-safe shutdown of pending order tasks that never received a response.","solutions":["Read the joined messages to identify which sub-step(s) failed; each segment names one underlying cause","Check network/WS connectivity to Deribit and retry the disconnect once tasks have settled","Ensure you do not double-disconnect or drop the client while requests are in flight","If a task hangs, inspect session_tasks/pending_tasks shutdown paths (TaskGroupGuard) for blocking joins and consider a shutdown timeout"],"exampleFix":"// before: blindly retrying connect after failed teardown\nclient.connect().await?;\n// after: surface and log each aggregated cause before reconnecting\nif let Err(e) = client.disconnect().await {\n    for cause in e.to_string().split(\"; \") {\n        tracing::warn!(cause, \"teardown error\");\n    }\n}\nclient.connect().await?;","handlingStrategy":"try-catch","validationCode":"// Ensure clean state before teardown\nassert!(!client.is_connected(), \"already disconnected\");","typeGuard":null,"tryCatchPattern":"match client.disconnect().await {\n    Err(e) => e.to_string().split(\"; \").for_each(|c| log::warn!(\"teardown: {c}\")),\n    Ok(()) => {},\n}","preventionTips":["Don't drop the client while requests are in flight","Avoid double-disconnect; track connection state","Ensure network reachability before disconnect so shutdown signaling succeeds"],"tags":["websocket","teardown","aggregated-errors","rust","deribit"],"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-14T00:17:10.932Z"}