{"record":{"id":"6781186b808ab3ba","repo":"nautechsystems/nautilus_trader","slug":"failed-to-get-dex-last-synced-block-e","errorCode":null,"errorMessage":"Failed to get dex last synced block: {e}","messagePattern":"Failed to get dex last synced block: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/cache/database.rs","lineNumber":1519,"sourceCode":"    pub async fn get_dex_last_synced_block(\n        &self,\n        chain_id: u32,\n        dex: &DexType,\n    ) -> anyhow::Result<Option<u64>> {\n        let result = sqlx::query_as::<_, (Option<i64>,)>(\n            \"\n            SELECT\n                last_full_sync_pools_block_number\n            FROM dex\n            WHERE chain_id = $1\n            AND name = $2\n            \",\n        )\n        .bind(chain_id as i32)\n        .bind(dex.to_string())\n        .fetch_optional(&self.pool)\n        .await\n        .map_err(|e| anyhow::anyhow!(\"Failed to get dex last synced block: {e}\"))?;\n\n        Ok(result.and_then(|(block_number,)| block_number.map(|b| b as u64)))\n    }\n\n    /// Retrieves the last synced block number for a pool.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the database query fails.\n    pub async fn get_pool_last_synced_block(\n        &self,\n        chain_id: u32,\n        dex: &DexType,\n        pool_identifier: &PoolIdentifier,\n    ) -> anyhow::Result<Option<u64>> {\n        let result = sqlx::query_as::<_, (Option<i64>,)>(\n            \"\n            SELECT","sourceCodeStart":1501,"sourceCodeEnd":1537,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/cache/database.rs#L1501-L1537","documentation":"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)).","triggerScenarios":"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.","commonSituations":"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).","solutions":["Run migrations to create the DEX checkpoint table","Verify connectivity to Postgres and pool health","Add/verify an index on (chain_id, dex) if timeouts occur on large tables","Treat as transient and retry; the read is safe to repeat"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// Check table availability first\nsqlx::query(\"SELECT 1 FROM dex_sync_checkpoints LIMIT 1\").fetch_optional(&pool).await?;","typeGuard":null,"tryCatchPattern":"let last_block = match get_dex_last_synced_block(chain_id, dex).await {\n    Ok(b) => b.unwrap_or(start_block),\n    Err(e) => { tracing::warn!(\"checkpoint read failed, using configured start: {e}\"); Some(start_block) }\n};","preventionTips":["Fall back to a configured start block when the checkpoint is unreadable","Index (chain_id, dex) to keep the lookup fast","Apply migrations on deploy"],"tags":["database","sqlx","read-failure","sync-checkpoint"],"backgroundTag":"sql-query-failed","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"}