nautechsystems/nautilus_trader · error

errors.join("; ")

Error message

errors.join("; ")

What it means

teardown_transports collects the error message of every individual transport teardown failure and, if any occurred, aborts with a single error whose message is all failures joined with "; ". This error surfaces when one or more OKX websocket/HTTP transports failed to shut down cleanly during connect_session, connect, or disconnect.

Source

Thrown at crates/adapters/okx/src/data.rs:1176

        self.is_connected.store(false, Ordering::Release);

        let mut errors = Vec::new();
        if let Err(e) = task_result {
            errors.push(e.to_string());
        }

        if let Err(e) = public_result {
            errors.push(e.to_string());
        }

        if let Err(e) = business_result {
            errors.push(e.to_string());
        }

        if errors.is_empty() {
            Ok(())
        } else {
            anyhow::bail!(errors.join("; "))
        }
    }
}

fn handle_book_sequence_outcome(
    outcome: BookSequenceOutcome,
    instrument_id: InstrumentId,
    book_channels: &Arc<AtomicMap<InstrumentId, OKXBookChannel>>,
    book_sync: &BookSyncTracker,
    recovery_ws: Option<&OKXWebSocketClient>,
    snapshot_timeout: Duration,
    tasks: &TaskSpawner,
) -> bool {
    match outcome {
        BookSequenceOutcome::Accept => true,
        BookSequenceOutcome::Suppress => false,
        BookSequenceOutcome::Recover {
            last_seq_id,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Read the joined message to identify which transports failed and fix the root cause of each underlying error (usually a network or task-join issue)
  2. Retry disconnect after a short delay — teardown failures during a network partition often resolve once connectivity returns
  3. Ensure disconnect is not called concurrently with reconnect logic; serialize connection lifecycle calls
  4. If a task was already finished, tolerate AlreadyClosed-style teardown errors by logging instead of failing shutdown

Example fix

// before
client.disconnect().await?; // bails with joined teardown errors
// after
if let Err(e) = client.disconnect().await {
    log::warn!("teardown reported failures (may be benign on shutdown): {e}");
}
Defensive patterns

Strategy: try-catch

Try / catch

if let Err(e) = client.disconnect().await {
    log::warn!("transport teardown reported failures: {e}"); // joined per-transport messages
    // inspect individual messages before deciding to retry or escalate
}

Prevention

When it happens

Trigger: Calling connect, connect_session, or disconnect on the OKX data client when at least one transport's teardown (e.g. closing a websocket, cancelling a stream task, joining a handle) returns an Err; all collected messages are joined and bailed.

Common situations: Network partitions during shutdown causing websocket close timeouts; tasks already aborted/panicked so joining fails; calling disconnect while transports are mid-reconnect; runtime shutdown racing transport lifecycles.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


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