nautechsystems/nautilus_trader · error · anyhow::Error
Architect AX data WebSocket handler failed: {error}
Error message
Architect AX data WebSocket handler failed: {error} What it means
Returned by the Architect AX data WebSocket client's close(). After aborting, it joins the handler task and maps the outcome: if the handler task ended in an error (TaskJoinOutcome::Failed), close() propagates that error wrapped in this anyhow message instead of returning Ok.
Source
Thrown at crates/adapters/architect_ax/src/websocket/data/client.rs:1078
self.cancellation_token.load().cancel();
let _ = self.send_cmd(HandlerCommand::Disconnect).await;
tokio::time::sleep(Duration::from_millis(50)).await;
self.signal.store(true, Ordering::Release);
let outcome = self
.task_handle
.finish(Duration::from_secs(2), Duration::from_secs(2))
.await;
*self.reconnect_headers.lock() = None;
if let Some(control) = &self.socket_control {
control.deregister();
}
match outcome {
None | Some(TaskJoinOutcome::Completed(()) | TaskJoinOutcome::Aborted) => Ok(()),
Some(TaskJoinOutcome::Failed(error)) => Err(anyhow::anyhow!(
"Architect AX data WebSocket handler failed: {error}"
)),
Some(TaskJoinOutcome::Incomplete) => Err(anyhow::anyhow!(
"Architect AX data WebSocket handler did not stop after abort"
)),
}
}
async fn send_cmd(&self, cmd: HandlerCommand) -> AxWsResult<()> {
let guard = self.cmd_tx.read().await;
guard
.send(cmd)
.map_err(|e| AxWsClientError::ChannelError(e.to_string()))
}
}
impl Drop for AxMdWebSocketClient {
fn drop(&mut self) {View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect the inner handler error (the {error} payload) to find the root cause before looking at close() itself
- Check server/connectivity logs around shutdown time for why the handler task failed
- Ensure close() is only called during teardown and handle the returned Err as a non-fatal shutdown warning if the session is ending anyway
- Update the adapter if the root cause is a handler bug on specific message types
Example fix
// before
client.close().await?; // may fail with handler error
// after
if let Err(e) = client.close().await {
tracing::warn!("data ws close: {e:#}"); // handler already failed; teardown continues
} Defensive patterns
Strategy: try-catch
Try / catch
// Rust
match client.close().await {
Ok(()) => {},
Err(e) => tracing::warn!("data ws handler failed on close: {e:#}"),
} Prevention
- Ensure the handler task handles stream errors gracefully instead of returning Err on transient failures
- Close the client during normal teardown, not after known handler failures you haven't diagnosed
- Keep cancellation checks in the handler loop so aborts are honored
- Log the inner error immediately — it names the root cause
When it happens
Trigger: Calling DataWebSocketClient::close() while the internal data handler task has terminated with an error — e.g. the handler failed on a malformed inbound frame, a send-channel error, or an unexpected stream termination rather than completing or being aborted cleanly.
Common situations: The remote feed dropped the connection mid-session with a handler-level error; a code bug in the message handler caused a panic/result error; shutdown raced with an already-failed handler in tests or teardown.
Related errors
- Polymarket RTDS task shutdown failed: {}
- RTDS connect was canceled by shutdown
- Failed to terminate Coinbase session tasks: {e}
- failed to finish Binance Futures data command tasks: {e}
- Binance Futures data teardown failed: {}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/7242b49b9eddd6bc.
Report an issue: GitHub.