{"record":{"id":"d91587e284832ded","repo":"nautechsystems/nautilus_trader","slug":"betfair-data-shutdown-failed","errorCode":null,"errorMessage":"Betfair data shutdown failed: {}","messagePattern":"Betfair data shutdown failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/betfair/src/data.rs","lineNumber":297,"sourceCode":"\n        if let Err(e) = self.finish_tasks().await {\n            self.shutdown_errors.push(e.to_string());\n        }\n        self.is_connected.store(false, Ordering::Release);\n        self.deregister_socket_controls();\n\n        if self.stream_client.is_none()\n            && self.race_stream_client.is_none()\n            && self.cricket_stream_client.is_none()\n        {\n            self.stream_shutdowns.lock().clear();\n        }\n\n        if self.shutdown_errors.is_empty() {\n            Ok(())\n        } else {\n            let errors = std::mem::take(&mut self.shutdown_errors);\n            anyhow::bail!(\"Betfair data shutdown failed: {}\", errors.join(\"; \"))\n        }\n    }\n\n    fn create_stream_handler(\n        data_sender: tokio::sync::mpsc::UnboundedSender<DataEvent>,\n        instruments: Arc<AtomicMap<InstrumentId, InstrumentAny>>,\n        currency: Currency,\n        min_notional: Option<Money>,\n        reconnect_tx: tokio::sync::mpsc::UnboundedSender<()>,\n        clock: &'static AtomicTime,\n    ) -> StreamMessageHandler {\n        // Track cumulative traded volumes per (instrument_id, price) to compute\n        // incremental trade sizes. Betfair `trd` fields report totals, not deltas.\n        let traded_volumes: Arc<Mutex<AHashMap<(InstrumentId, Decimal), Decimal>>> =\n            Arc::new(Mutex::new(AHashMap::new()));\n        let has_initial_connection = Arc::new(AtomicBool::new(false));\n\n        Arc::new(move |msg: StreamMessage| {","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/betfair/src/data.rs#L279-L315","documentation":"When a Betfair data client disconnects or fails during connect, teardown_partial_connect collects errors from shutting down individual tasks/streams into self.shutdown_errors. If any were recorded, teardown bails with this aggregated message so partial-connect failures surface instead of being silently dropped.","triggerScenarios":"disconnect() or a failed connect()/prepare_task_groups path where one or more background tasks (stream reader, heartbeats, subscriptions) fail to cancel/join cleanly, populating shutdown_errors.","commonSituations":"Network drop mid-connect leaving a task unresponsive; task panics during teardown; calling disconnect while the stream handler is blocked on I/O.","solutions":["Inspect the joined error list in the message to identify which task failed and fix the root cause","Ensure disconnect() is awaited and the runtime is not shutting down mid-await","Retry connect after a clean disconnect; report if a specific task reliably fails teardown"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match client.disconnect().await {\n    Ok(()) => {},\n    Err(e) if e.to_string().starts_with(\"Betfair data shutdown failed\") => {\n        warn!(\"partial teardown: {e:#}\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Always await disconnect() on a live tokio runtime before dropping the client","Avoid cancelling tasks mid-connect; let connect finish or fail first","Monitor and log shutdown_errors to spot recurring task failures"],"tags":["betfair","shutdown","lifecycle","network"],"backgroundTag":"shutdown-failure","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"}