Skip to content

Commit cfb25e0

Browse files
committed
fix: return proper error rather than persisting error message on snapshot
Signed-off-by: StandingMan <[email protected]>
1 parent bc86d10 commit cfb25e0

File tree

1 file changed

+82
-4
lines changed

1 file changed

+82
-4
lines changed

crates/iceberg/src/spec/snapshot.rs

Lines changed: 82 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -266,9 +266,9 @@ pub(super) mod _serde {
266266
use serde::{Deserialize, Serialize};
267267

268268
use super::{Operation, Snapshot, Summary};
269-
use crate::Error;
270269
use crate::spec::SchemaId;
271270
use crate::spec::snapshot::SnapshotRowRange;
271+
use crate::{Error, ErrorKind};
272272

273273
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
274274
#[serde(rename_all = "kebab-case")]
@@ -408,9 +408,19 @@ pub(super) mod _serde {
408408
timestamp_ms: v1.timestamp_ms,
409409
manifest_list: match (v1.manifest_list, v1.manifests) {
410410
(Some(file), None) => file,
411-
(Some(_), Some(_)) => "Invalid v1 snapshot, when manifest list provided, manifest files should be omitted".to_string(),
412-
(None, _) => "Unsupported v1 snapshot, only manifest list is supported".to_string()
413-
},
411+
(Some(_), Some(_)) => {
412+
return Err(Error::new(
413+
ErrorKind::Unexpected,
414+
"v1 snapshot invariant violated: manifest_list and manifests are both set",
415+
));
416+
}
417+
(None, _) => {
418+
return Err(Error::new(
419+
ErrorKind::FeatureUnsupported,
420+
"v1 snapshot invariant violated: manifest_list is missing",
421+
));
422+
}
423+
},
414424
summary: v1.summary.unwrap_or(Summary {
415425
operation: Operation::default(),
416426
additional_properties: HashMap::new(),
@@ -517,6 +527,7 @@ mod tests {
517527

518528
use chrono::{TimeZone, Utc};
519529

530+
use crate::spec::TableMetadata;
520531
use crate::spec::snapshot::_serde::SnapshotV1;
521532
use crate::spec::snapshot::{Operation, Snapshot, Summary};
522533

@@ -604,6 +615,73 @@ mod tests {
604615
);
605616
}
606617

618+
#[test]
619+
fn test_v1_snapshot_with_manifest_list_and_manifests() {
620+
{
621+
let metadata = r#"
622+
{
623+
"format-version": 1,
624+
"table-uuid": "d20125c8-7284-442c-9aea-15fee620737c",
625+
"location": "s3://bucket/test/location",
626+
"last-updated-ms": 1700000000000,
627+
"last-column-id": 1,
628+
"schema": {
629+
"type": "struct",
630+
"fields": [
631+
{"id": 1, "name": "x", "required": true, "type": "long"}
632+
]
633+
},
634+
"partition-spec": [],
635+
"properties": {},
636+
"current-snapshot-id": 111111111,
637+
"snapshots": [
638+
{
639+
"snapshot-id": 111111111,
640+
"timestamp-ms": 1600000000000,
641+
"summary": {"operation": "append"},
642+
"manifest-list": "s3://bucket/metadata/snap-123.avro",
643+
"manifests": ["s3://bucket/metadata/manifest-1.avro"]
644+
}
645+
]
646+
}
647+
"#;
648+
649+
let result = serde_json::from_str::<TableMetadata>(metadata);
650+
assert!(result.is_err());
651+
}
652+
653+
{
654+
let metadata = r#"
655+
{
656+
"format-version": 1,
657+
"table-uuid": "d20125c8-7284-442c-9aea-15fee620737c",
658+
"location": "s3://bucket/test/location",
659+
"last-updated-ms": 1700000000000,
660+
"last-column-id": 1,
661+
"schema": {
662+
"type": "struct",
663+
"fields": [
664+
{"id": 1, "name": "x", "required": true, "type": "long"}
665+
]
666+
},
667+
"partition-spec": [],
668+
"properties": {},
669+
"current-snapshot-id": 111111111,
670+
"snapshots": [
671+
{
672+
"snapshot-id": 111111111,
673+
"timestamp-ms": 1600000000000,
674+
"summary": {"operation": "append"},
675+
"manifests": ["s3://bucket/metadata/manifest-1.avro"]
676+
}
677+
]
678+
}
679+
"#;
680+
let result = serde_json::from_str::<TableMetadata>(metadata);
681+
assert!(result.is_err());
682+
}
683+
}
684+
607685
#[test]
608686
fn test_snapshot_v1_to_v2_with_missing_summary() {
609687
use crate::spec::snapshot::_serde::SnapshotV1;

0 commit comments

Comments
 (0)