nautechsystems/nautilus_trader · error · anyhow::Error

Failed to get dex last synced block: {e}

Error message

Failed to get dex last synced block: {e}

What it means

Wraps a sqlx error from the SELECT that reads the stored last synced block number for a DEX on a chain. The library throws it only when the query itself fails, not when no row exists (that returns None/Ok(None)).

Source

Thrown at crates/adapters/blockchain/src/cache/database.rs:1519

    pub async fn get_dex_last_synced_block(
        &self,
        chain_id: u32,
        dex: &DexType,
    ) -> anyhow::Result<Option<u64>> {
        let result = sqlx::query_as::<_, (Option<i64>,)>(
            "
            SELECT
                last_full_sync_pools_block_number
            FROM dex
            WHERE chain_id = $1
            AND name = $2
            ",
        )
        .bind(chain_id as i32)
        .bind(dex.to_string())
        .fetch_optional(&self.pool)
        .await
        .map_err(|e| anyhow::anyhow!("Failed to get dex last synced block: {e}"))?;

        Ok(result.and_then(|(block_number,)| block_number.map(|b| b as u64)))
    }

    /// Retrieves the last synced block number for a pool.
    ///
    /// # Errors
    ///
    /// Returns an error if the database query fails.
    pub async fn get_pool_last_synced_block(
        &self,
        chain_id: u32,
        dex: &DexType,
        pool_identifier: &PoolIdentifier,
    ) -> anyhow::Result<Option<u64>> {
        let result = sqlx::query_as::<_, (Option<i64>,)>(
            "
            SELECT

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Run migrations to create the DEX checkpoint table
  2. Verify connectivity to Postgres and pool health
  3. Add/verify an index on (chain_id, dex) if timeouts occur on large tables
  4. Treat as transient and retry; the read is safe to repeat
Defensive patterns

Strategy: fallback

Validate before calling

// Check table availability first
sqlx::query("SELECT 1 FROM dex_sync_checkpoints LIMIT 1").fetch_optional(&pool).await?;

Try / catch

let last_block = match get_dex_last_synced_block(chain_id, dex).await {
    Ok(b) => b.unwrap_or(start_block),
    Err(e) => { tracing::warn!("checkpoint read failed, using configured start: {e}"); Some(start_block) }
};

Prevention

When it happens

Trigger: Calling `get_dex_last_synced_block(chain_id, dex)` when the connection is broken, the table is missing (migrations not applied), or the query times out under load.

Common situations: New deployment without migrations; database restarted; connectivity drop between indexer and Postgres; statement timeout because the table grew very large without an index on (chain_id, dex).

Understand the failure class

Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.

Related errors


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