This is an automated email from the ASF dual-hosted git repository.
alamb pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-rs-object-store.git
The following commit(s) were added to refs/heads/main by this push:
new 493a5d0 fix: Add more details on what isn't implemented (#575)
493a5d0 is described below
commit 493a5d07d29b12a5731bf112d3ab5df8d0de9616
Author: Carol (Nichols || Goulding)
<[email protected]>
AuthorDate: Thu Dec 18 13:09:50 2025 -0500
fix: Add more details on what isn't implemented (#575)
Fixes #572.
---
src/aws/mod.rs | 13 +++++++++++--
src/http/mod.rs | 10 ++++++++--
src/integration.rs | 6 +++---
src/lib.rs | 13 +++++++++++--
src/local.rs | 15 ++++++++++++---
5 files changed, 45 insertions(+), 12 deletions(-)
diff --git a/src/aws/mod.rs b/src/aws/mod.rs
index dd2cf6f..030590a 100644
--- a/src/aws/mod.rs
+++ b/src/aws/mod.rs
@@ -180,7 +180,11 @@ impl ObjectStore for AmazonS3 {
match (mode, &self.client.config.conditional_put) {
(PutMode::Overwrite, _) => request.idempotent(true).do_put().await,
- (PutMode::Create, S3ConditionalPut::Disabled) =>
Err(Error::NotImplemented),
+ (PutMode::Create, S3ConditionalPut::Disabled) =>
Err(Error::NotImplemented {
+ operation:
+ "`put_opts` with mode `PutMode::Create` when conditional
put is disabled".into(),
+ implementer: self.to_string(),
+ }),
(PutMode::Create, S3ConditionalPut::ETagMatch) => {
match request.header(&IF_NONE_MATCH, "*").do_put().await {
// Technically If-None-Match should return NotModified but
some stores,
@@ -222,7 +226,12 @@ impl ObjectStore for AmazonS3 {
r => r,
}
}
- S3ConditionalPut::Disabled => Err(Error::NotImplemented),
+ S3ConditionalPut::Disabled => Err(Error::NotImplemented {
+ operation:
+ "`put_opts` with mode `PutMode::Update` when
conditional put is disabled"
+ .into(),
+ implementer: self.to_string(),
+ }),
}
}
}
diff --git a/src/http/mod.rs b/src/http/mod.rs
index e241002..9e5af9a 100644
--- a/src/http/mod.rs
+++ b/src/http/mod.rs
@@ -104,7 +104,10 @@ impl ObjectStore for HttpStore {
) -> Result<PutResult> {
if opts.mode != PutMode::Overwrite {
// TODO: Add support for If header -
https://datatracker.ietf.org/doc/html/rfc2518#section-9.4
- return Err(crate::Error::NotImplemented);
+ return Err(crate::Error::NotImplemented {
+ operation: "`put_opts` with a mode other than
`PutMode::Overwrite`".into(),
+ implementer: self.to_string(),
+ });
}
let response = self.client.put(location, payload,
opts.attributes).await?;
@@ -125,7 +128,10 @@ impl ObjectStore for HttpStore {
_location: &Path,
_opts: PutMultipartOptions,
) -> Result<Box<dyn MultipartUpload>> {
- Err(crate::Error::NotImplemented)
+ Err(crate::Error::NotImplemented {
+ operation: "`put_multipart_opts`".into(),
+ implementer: self.to_string(),
+ })
}
async fn get_opts(&self, location: &Path, options: GetOptions) ->
Result<GetResult> {
diff --git a/src/integration.rs b/src/integration.rs
index bc79f69..5c601b5 100644
--- a/src/integration.rs
+++ b/src/integration.rs
@@ -478,7 +478,7 @@ pub async fn put_get_attributes(integration: &dyn
ObjectStore) {
let r = integration.get(&path).await.unwrap();
assert_eq!(r.attributes, attributes);
}
- Err(Error::NotImplemented) => {}
+ Err(Error::NotImplemented { .. }) => {}
Err(e) => panic!("{e}"),
}
@@ -491,7 +491,7 @@ pub async fn put_get_attributes(integration: &dyn
ObjectStore) {
let r = integration.get(&path).await.unwrap();
assert_eq!(r.attributes, attributes);
}
- Err(Error::NotImplemented) => {}
+ Err(Error::NotImplemented { .. }) => {}
Err(e) => panic!("{e}"),
}
}
@@ -606,7 +606,7 @@ pub async fn put_opts(storage: &dyn ObjectStore,
supports_update: bool) {
.put_opts(&path, "c".into(),
PutMode::Update(v1.clone().into()).into())
.await
.unwrap_err();
- assert!(matches!(err, Error::NotImplemented), "{err}");
+ assert!(matches!(err, Error::NotImplemented { .. }), "{err}");
return;
}
diff --git a/src/lib.rs b/src/lib.rs
index 3448055..d5c0cb5 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2049,8 +2049,17 @@ pub enum Error {
},
/// Error when an operation is not implemented
- #[error("Operation not yet implemented.")]
- NotImplemented,
+ #[error("Operation {operation} not yet implemented by {implementer}.")]
+ NotImplemented {
+ /// What isn't implemented. Should include at least the method
+ /// name that was called; could also include other relevant
+ /// subcontexts.
+ operation: String,
+
+ /// Which driver this is that hasn't implemented this operation,
+ /// to aid debugging in contexts that may be using multiple
implementations.
+ implementer: String,
+ },
/// Error when the used credentials don't have enough permission
/// to perform the requested operation
diff --git a/src/local.rs b/src/local.rs
index 003e7d7..8f18aa6 100644
--- a/src/local.rs
+++ b/src/local.rs
@@ -330,11 +330,17 @@ impl ObjectStore for LocalFileSystem {
opts: PutOptions,
) -> Result<PutResult> {
if matches!(opts.mode, PutMode::Update(_)) {
- return Err(crate::Error::NotImplemented);
+ return Err(crate::Error::NotImplemented {
+ operation: "`put_opts` with mode `PutMode::Update`".into(),
+ implementer: self.to_string(),
+ });
}
if !opts.attributes.is_empty() {
- return Err(crate::Error::NotImplemented);
+ return Err(crate::Error::NotImplemented {
+ operation: "`put_opts` with `opts.attributes`
specified".into(),
+ implementer: self.to_string(),
+ });
}
let path = self.path_to_filesystem(location)?;
@@ -397,7 +403,10 @@ impl ObjectStore for LocalFileSystem {
opts: PutMultipartOptions,
) -> Result<Box<dyn MultipartUpload>> {
if !opts.attributes.is_empty() {
- return Err(crate::Error::NotImplemented);
+ return Err(crate::Error::NotImplemented {
+ operation: "`put_multipart_opts` with `opts.attributes`
specified".into(),
+ implementer: self.to_string(),
+ });
}
let dest = self.path_to_filesystem(location)?;