You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iceberg.apache.org by sc...@apache.org on 2026/06/10 17:14:41 UTC

(iceberg-rust) branch main updated: fix(s3tables): add TableNotFound error handling (#2595)

This is an automated email from the ASF dual-hosted git repository.

CTTY pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-rust.git


The following commit(s) were added to refs/heads/main by this push:
     new c527d7fbf fix(s3tables): add TableNotFound error handling (#2595)
c527d7fbf is described below

commit c527d7fbf49831fab4555794c365003ac107e1b8
Author: Daniel Carl Jones <dj...@amazon.com>
AuthorDate: Wed Jun 10 18:14:36 2026 +0100

    fix(s3tables): add TableNotFound error handling (#2595)
    
    ## Which issue does this PR close?
    
    - Closes #2594.
    
    ## What changes are included in this PR?
    
    This PR updates table loading in the S3 Tables catalog to first check
    for a table not found error from the S3 Tables service, before allowing
    the fallback mapping of SDK error into an Iceberg `Unexpected` error.
    
    ## Are these changes tested?
    
    Yes, I've added and run new integration tests.
---
 crates/catalog/s3tables/src/catalog.rs | 38 +++++++++++++++++++++++++++++-----
 1 file changed, 33 insertions(+), 5 deletions(-)

diff --git a/crates/catalog/s3tables/src/catalog.rs b/crates/catalog/s3tables/src/catalog.rs
index 03f4a28de..c7c92ab44 100644
--- a/crates/catalog/s3tables/src/catalog.rs
+++ b/crates/catalog/s3tables/src/catalog.rs
@@ -23,7 +23,7 @@ use std::sync::Arc;
 use async_trait::async_trait;
 use aws_sdk_s3tables::operation::create_table::CreateTableOutput;
 use aws_sdk_s3tables::operation::get_namespace::GetNamespaceOutput;
-use aws_sdk_s3tables::operation::get_table::GetTableOutput;
+use aws_sdk_s3tables::operation::get_table::{GetTableError, GetTableOutput};
 use aws_sdk_s3tables::operation::list_tables::ListTablesOutput;
 use aws_sdk_s3tables::operation::update_table_metadata_location::UpdateTableMetadataLocationError;
 use aws_sdk_s3tables::types::OpenTableFormat;
@@ -240,7 +240,23 @@ impl S3TablesCatalog {
             .table_bucket_arn(self.config.table_bucket_arn.clone())
             .namespace(table_ident.namespace().to_url_string())
             .name(table_ident.name());
-        let resp: GetTableOutput = req.send().await.map_err(from_aws_sdk_error)?;
+
+        let resp = req.send().await.map_err(|err| {
+            if err
+                .as_service_error()
+                .is_some_and(GetTableError::is_not_found_exception)
+            {
+                // S3 Tables GetTable API only reports that the resource was not found, and does not distinguish between namespaces and tables.
+                // https://docs.aws.amazon.com/AmazonS3/latest/API/API_s3Buckets_GetTable.html#API_s3Buckets_GetTable_Errors
+                Error::new(
+                    ErrorKind::TableNotFound,
+                    format!("Table {table_ident} is not found, either because the namespace or table did not exist"),
+                )
+                .with_source(err)
+            } else {
+                from_aws_sdk_error(err)
+            }
+        })?;
 
         // when a table is created, it's possible that the metadata location is not set.
         let metadata_location = resp.metadata_location().ok_or_else(|| {
@@ -782,14 +798,26 @@ mod tests {
             Err(e) => panic!("Error loading catalog: {e}"),
         };
 
-        let table = catalog
+        let _table = catalog
             .load_table(&TableIdent::new(
                 NamespaceIdent::new("aws_s3_metadata".to_string()),
                 "query_storage_metadata".to_string(),
             ))
             .await
-            .unwrap();
-        println!("{table:?}");
+            .expect("table that exists should be loaded");
+
+        let load_table_err = catalog
+            .load_table(&TableIdent::new(
+                NamespaceIdent::new("not_a_namespace".to_string()),
+                "not_a_table_name".to_string(),
+            ))
+            .await
+            .expect_err("loading a table that does not exist should fail");
+        assert_eq!(
+            load_table_err.kind(),
+            ErrorKind::TableNotFound,
+            "must return table not found error for non-existent table"
+        );
     }
 
     #[tokio::test]