nautechsystems/nautilus_trader · error · anyhow::Error

std::mem::take(&mut self.shutdown_errors).join("; ")

Error message

std::mem::take(&mut self.shutdown_errors).join("; ")

What it means

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.

Source

Thrown at crates/adapters/dydx/src/data.rs:299

        Ok(())
    }

    async fn finish_shutdown(&mut self) -> anyhow::Result<()> {
        if let Err(e) = self
            .ws_client
            .disconnect()
            .await
            .context("failed to disconnect dYdX websocket")
        {
            self.shutdown_errors.push(e.to_string());
        }

        if let Err(e) = self.finish_tasks().await {
            self.shutdown_errors.push(e.to_string());
        }

        if !self.shutdown_errors.is_empty() {
            anyhow::bail!(std::mem::take(&mut self.shutdown_errors).join("; "));
        }
        Ok(())
    }

    async fn teardown_partial_connect(&mut self) -> anyhow::Result<()> {
        self.session_tasks.begin_shutdown();
        self.command_tasks.begin_shutdown();
        self.ws_client.begin_shutdown();
        let shutdown_result = self.finish_shutdown().await;
        self.is_connected.store(false, Ordering::Release);
        shutdown_result
    }

    async fn bootstrap_instruments(&self) -> anyhow::Result<Vec<InstrumentAny>> {
        self.http_client
            .fetch_and_cache_instruments()
            .await
            .context("failed to load instruments from dYdX")?;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Read the joined message to identify each underlying task error and fix the root cause
  2. Check network/proxy stability if errors are WebSocket-related
  3. Log shutdown errors at teardown and treat transient ones as non-fatal in the calling strategy
Defensive patterns

Strategy: try-catch

Try / catch

match client.disconnect().await {
    Ok(()) => {},
    Err(e) => {
        // e contains all task shutdown errors joined by '; '
        for msg in e.to_string().split("; ") {
            log::warn!("shutdown task error: {msg}");
        }
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/e9895c20af87ac4c. Report an issue: GitHub.