From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id CD86F1FF138 for ; Wed, 04 Mar 2026 14:58:39 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id C0F51AFEB; Wed, 4 Mar 2026 14:59:41 +0100 (CET) From: Christian Ebner To: pbs-devel@lists.proxmox.com Subject: [PATCH proxmox v2 4/4] s3-client: return list of errors when deleting by prefix Date: Wed, 4 Mar 2026 14:59:20 +0100 Message-ID: <20260304135922.717714-5-c.ebner@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260304135922.717714-1-c.ebner@proxmox.com> References: <20260304135922.717714-1-c.ebner@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1772632751173 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.053 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: FXDC2S46KBFSEEWPQGQFX4G7RN3JWLZS X-Message-ID-Hash: FXDC2S46KBFSEEWPQGQFX4G7RN3JWLZS X-MailFrom: c.ebner@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox Backup Server development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Previously only a boolean flag indicating whether there was an error or not was returned. Now return a list of errors which occurred when performing object deletion. This allows to better log and inspect error causes. Further, since this is now part of the public facing api, expose the DeleteObjectError type to allow for error handling on the call side. Signed-off-by: Christian Ebner --- changes since version 1: - not present in previous version proxmox-s3-client/src/client.rs | 18 +++++++++--------- proxmox-s3-client/src/lib.rs | 2 ++ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/proxmox-s3-client/src/client.rs b/proxmox-s3-client/src/client.rs index 5eea4dd3..435b3992 100644 --- a/proxmox-s3-client/src/client.rs +++ b/proxmox-s3-client/src/client.rs @@ -666,12 +666,12 @@ impl S3Client { /// Delete objects by given key prefix. /// Requires at least 2 api calls. - pub async fn delete_objects_by_prefix(&self, prefix: &S3PathPrefix) -> Result { + pub async fn delete_objects_by_prefix(&self, prefix: &S3PathPrefix) -> Result, Error> { // S3 API does not provide a convenient way to delete objects by key prefix. // List all objects with given group prefix and delete all objects found, so this // requires at least 2 API calls. let mut next_continuation_token: Option = None; - let mut delete_errors = false; + let mut delete_errors = Vec::new(); loop { let list_objects_result = self .list_objects_v2(prefix, next_continuation_token.as_deref()) @@ -684,8 +684,8 @@ impl S3Client { .collect(); let response = self.delete_objects(&objects_to_delete).await?; - if response.error.is_some() { - delete_errors = true; + if let Some(mut errors) = response.error { + delete_errors.append(&mut errors); } if list_objects_result.is_truncated { @@ -713,12 +713,12 @@ impl S3Client { prefix: &S3PathPrefix, suffix: &str, excldue_from_parent: &[&str], - ) -> Result { + ) -> Result, Error> { // S3 API does not provide a convenient way to delete objects by key prefix. // List all objects with given group prefix and delete all objects found, so this // requires at least 2 API calls. let mut next_continuation_token: Option = None; - let mut delete_errors = false; + let mut delete_errors = Vec::new(); let mut prefix_filters = Vec::new(); let mut list_objects = Vec::new(); loop { @@ -772,9 +772,9 @@ impl S3Client { .collect(); for objects in objects_to_delete.chunks(1000) { - let result = self.delete_objects(objects).await?; - if result.error.is_some() { - delete_errors = true; + let response = self.delete_objects(objects).await?; + if let Some(mut errors) = response.error { + delete_errors.append(&mut errors); } } diff --git a/proxmox-s3-client/src/lib.rs b/proxmox-s3-client/src/lib.rs index d02fd0dc..5c8c4b08 100644 --- a/proxmox-s3-client/src/lib.rs +++ b/proxmox-s3-client/src/lib.rs @@ -33,3 +33,5 @@ mod object_key; pub use object_key::S3ObjectKey; #[cfg(feature = "impl")] mod response_reader; +#[cfg(feature = "impl")] +pub use response_reader::DeleteObjectError; -- 2.47.3