List what a hold export can't read instead of skipping it (LH-12)
ci / fork-checks (pull_request) Successful in 49s
ci / build (pull_request) Successful in 11m32s

An item the hold covers whose stored record or content can't be read
goes in exceptions.csv with the path it would have had and the reason,
rather than being left out silently. The file is always in the ZIP, so a
header-only one shows nothing was missed, and manifest.sha256 carries
its hash beside the manifest's.
This commit is contained in:
2026-09-27 22:15:05 -07:00
parent 3978cf5785
commit 5c506b9d2b
2 changed files with 133 additions and 21 deletions
+7 -1
View File
@@ -494,7 +494,7 @@ pub async fn test(test: &mut TestServer) {
assert!(
names
.iter()
.all(|n| n.starts_with("[email protected]/") || n.starts_with("manifest.")),
.all(|n| n.starts_with("[email protected]/") || n.starts_with("manifest.") || n == "exceptions.csv"),
"LH-12: an account the hold doesn't cover was exported: {names:?}"
);
let mut manifest = String::new();
@@ -508,6 +508,12 @@ pub async fn test(test: &mut TestServer) {
.collect();
assert!(hash.starts_with(&expected), "LH-12: the manifest's hash doesn't match");
assert!(manifest.contains(",true,"), "LH-12: nothing marked archived: {manifest}");
let mut exceptions = String::new();
std::io::Read::read_to_string(&mut zip.by_name("exceptions.csv").unwrap(), &mut exceptions).unwrap();
assert_eq!(
exceptions, "path,account,kind,folder,date,archived,reason\n",
"LH-12: items the hold covers couldn't be read"
);
// LH-13: only sysLegalHoldExport starts one
let (_, response) = frozen
.hold_call(