This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] 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 b802a7cab fix(catalog/s3tables): attach S3 Tables SDK error as source
in resulting Iceberg error (#3523)
b802a7cab is described below
commit b802a7cab1a370e552ddc3f00ed946706e0ce817
Author: Danny C Jones <[email protected]>
AuthorDate: Tue Oct 27 17:53:49 2026 +0000
fix(catalog/s3tables): attach S3 Tables SDK error as source in resulting
Iceberg error (#3523)
fix(catalog/s3tables): keep the SdkError as the source of SDK failures
from_aws_sdk_error and the commit path kept only a Debug render of the
SdkError, so callers could not downcast to the typed error to inspect
the service error code or status. Attach the SdkError itself as the
error source.
---
Cargo.lock | 1 -
crates/catalog/s3tables/Cargo.toml | 1 -
crates/catalog/s3tables/src/catalog.rs | 46 +++++++++++++++++++++++-----------
3 files changed, 31 insertions(+), 17 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 801e4597c..017d9b071 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3008,7 +3008,6 @@ dependencies = [
name = "iceberg-catalog-s3tables"
version = "0.10.1"
dependencies = [
- "anyhow",
"arrow-array",
"arrow-schema",
"async-trait",
diff --git a/crates/catalog/s3tables/Cargo.toml
b/crates/catalog/s3tables/Cargo.toml
index f7bfa0611..ef6f3e045 100644
--- a/crates/catalog/s3tables/Cargo.toml
+++ b/crates/catalog/s3tables/Cargo.toml
@@ -31,7 +31,6 @@ license = { workspace = true }
repository = { workspace = true }
[dependencies]
-anyhow = { workspace = true }
async-trait = { workspace = true }
aws-config = { workspace = true }
aws-sdk-s3tables = { workspace = true }
diff --git a/crates/catalog/s3tables/src/catalog.rs
b/crates/catalog/s3tables/src/catalog.rs
index 73127bd90..254f20ae3 100644
--- a/crates/catalog/s3tables/src/catalog.rs
+++ b/crates/catalog/s3tables/src/catalog.rs
@@ -724,25 +724,23 @@ impl Catalog for S3TablesCatalog {
.version_token(version_token)
.metadata_location(staged_metadata_location_str);
- let _ = builder.send().await.map_err(|e| {
- let error = e.into_service_error();
- match error {
- UpdateTableMetadataLocationError::ConflictException(_) =>
Error::new(
+ let _ = builder
+ .send()
+ .await
+ .map_err(|e| match e.as_service_error() {
+ Some(UpdateTableMetadataLocationError::ConflictException(_))
=> Error::new(
ErrorKind::CatalogCommitConflicts,
format!("Commit conflicted for table: {table_ident}"),
)
- .with_retryable(true),
- UpdateTableMetadataLocationError::NotFoundException(_) =>
Error::new(
+ .with_retryable(true)
+ .with_source(e),
+ Some(UpdateTableMetadataLocationError::NotFoundException(_))
=> Error::new(
ErrorKind::TableNotFound,
format!("Table {table_ident} is not found"),
- ),
- _ => Error::new(
- ErrorKind::Unexpected,
- "Operation failed for hitting aws sdk error",
- ),
- }
- .with_source(anyhow::Error::msg(format!("aws sdk error:
{error:?}")))
- })?;
+ )
+ .with_source(e),
+ _ => from_aws_sdk_error(e),
+ })?;
Ok(staged_table)
}
@@ -750,21 +748,39 @@ impl Catalog for S3TablesCatalog {
/// Format AWS SDK error into iceberg error
pub(crate) fn from_aws_sdk_error<T>(error:
aws_sdk_s3tables::error::SdkError<T>) -> Error
-where T: std::fmt::Debug {
+where T: std::error::Error + Send + Sync + 'static {
Error::new(
ErrorKind::Unexpected,
format!("Operation failed for hitting aws sdk error: {error:?}"),
)
+ .with_source(error)
}
#[cfg(test)]
mod tests {
+ use std::error::Error as _;
+
use futures::TryStreamExt;
use iceberg::spec::{NestedField, PrimitiveType, Schema, Type};
use iceberg::transaction::{ApplyTransactionAction, Transaction};
use super::*;
+ #[test]
+ fn test_from_aws_sdk_error_keeps_sdk_error_as_source() {
+ let err = from_aws_sdk_error(
+
aws_sdk_s3tables::error::SdkError::<GetTableError>::construction_failure("boom"),
+ );
+
+ assert_eq!(err.kind(), ErrorKind::Unexpected);
+ assert!(
+ err.source()
+ .and_then(|source| source
+
.downcast_ref::<aws_sdk_s3tables::error::SdkError<GetTableError>>())
+ .is_some()
+ );
+ }
+
async fn load_s3tables_catalog_from_env() ->
Result<Option<S3TablesCatalog>> {
let table_bucket_arn = match std::env::var("TABLE_BUCKET_ARN").ok() {
Some(table_bucket_arn) => table_bucket_arn,