Skip to content

Commit 43cc7f7

Browse files
committed
object_store/gcp: Migrate from snafu to thiserror
1 parent b7dbf44 commit 43cc7f7

File tree

3 files changed

+108
-86
lines changed

3 files changed

+108
-86
lines changed

object_store/src/gcp/builder.rs

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,40 +27,39 @@ use crate::gcp::{
2727
};
2828
use crate::{ClientConfigKey, ClientOptions, Result, RetryConfig, StaticCredentialProvider};
2929
use serde::{Deserialize, Serialize};
30-
use snafu::{OptionExt, ResultExt, Snafu};
3130
use std::str::FromStr;
3231
use std::sync::Arc;
3332
use url::Url;
3433

3534
use super::credential::{AuthorizedUserSigningCredentials, InstanceSigningCredentialProvider};
3635

37-
#[derive(Debug, Snafu)]
36+
#[derive(Debug, thiserror::Error)]
3837
enum Error {
39-
#[snafu(display("Missing bucket name"))]
38+
#[error("Missing bucket name")]
4039
MissingBucketName {},
4140

42-
#[snafu(display("One of service account path or service account key may be provided."))]
41+
#[error("One of service account path or service account key may be provided.")]
4342
ServiceAccountPathAndKeyProvided,
4443

45-
#[snafu(display("Unable parse source url. Url: {}, Error: {}", url, source))]
44+
#[error("Unable parse source url. Url: {}, Error: {}", url, source)]
4645
UnableToParseUrl {
4746
source: url::ParseError,
4847
url: String,
4948
},
5049

51-
#[snafu(display(
50+
#[error(
5251
"Unknown url scheme cannot be parsed into storage location: {}",
5352
scheme
54-
))]
53+
)]
5554
UnknownUrlScheme { scheme: String },
5655

57-
#[snafu(display("URL did not match any known pattern for scheme: {}", url))]
56+
#[error("URL did not match any known pattern for scheme: {}", url)]
5857
UrlNotRecognised { url: String },
5958

60-
#[snafu(display("Configuration key: '{}' is not known.", key))]
59+
#[error("Configuration key: '{}' is not known.", key)]
6160
UnknownConfigurationKey { key: String },
6261

63-
#[snafu(display("GCP credential error: {}", source))]
62+
#[error("GCP credential error: {}", source)]
6463
Credential { source: credential::Error },
6564
}
6665

@@ -316,12 +315,21 @@ impl GoogleCloudStorageBuilder {
316315
/// This is a separate member function to allow fallible computation to
317316
/// be deferred until [`Self::build`] which in turn allows deriving [`Clone`]
318317
fn parse_url(&mut self, url: &str) -> Result<()> {
319-
let parsed = Url::parse(url).context(UnableToParseUrlSnafu { url })?;
320-
let host = parsed.host_str().context(UrlNotRecognisedSnafu { url })?;
318+
let parsed = Url::parse(url).map_err(|source| Error::UnableToParseUrl {
319+
source,
320+
url: url.to_string(),
321+
})?;
322+
323+
let host = parsed.host_str().ok_or_else(|| Error::UrlNotRecognised {
324+
url: url.to_string(),
325+
})?;
321326

322327
match parsed.scheme() {
323328
"gs" => self.bucket_name = Some(host.to_string()),
324-
scheme => return Err(UnknownUrlSchemeSnafu { scheme }.build().into()),
329+
scheme => {
330+
let scheme = scheme.to_string();
331+
return Err(Error::UnknownUrlScheme { scheme }.into());
332+
}
325333
}
326334
Ok(())
327335
}
@@ -425,12 +433,14 @@ impl GoogleCloudStorageBuilder {
425433
// First try to initialize from the service account information.
426434
let service_account_credentials =
427435
match (self.service_account_path, self.service_account_key) {
428-
(Some(path), None) => {
429-
Some(ServiceAccountCredentials::from_file(path).context(CredentialSnafu)?)
430-
}
431-
(None, Some(key)) => {
432-
Some(ServiceAccountCredentials::from_key(&key).context(CredentialSnafu)?)
433-
}
436+
(Some(path), None) => Some(
437+
ServiceAccountCredentials::from_file(path)
438+
.map_err(|source| Error::Credential { source })?,
439+
),
440+
(None, Some(key)) => Some(
441+
ServiceAccountCredentials::from_key(&key)
442+
.map_err(|source| Error::Credential { source })?,
443+
),
434444
(None, None) => None,
435445
(Some(_), Some(_)) => return Err(Error::ServiceAccountPathAndKeyProvided.into()),
436446
};

object_store/src/gcp/client.rs

Lines changed: 49 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ use percent_encoding::{percent_encode, utf8_percent_encode, NON_ALPHANUMERIC};
4444
use reqwest::header::HeaderName;
4545
use reqwest::{Client, Method, RequestBuilder, Response, StatusCode};
4646
use serde::{Deserialize, Serialize};
47-
use snafu::{OptionExt, ResultExt, Snafu};
4847
use std::sync::Arc;
4948

5049
const VERSION_HEADER: &str = "x-goog-generation";
@@ -53,59 +52,59 @@ const USER_DEFINED_METADATA_HEADER_PREFIX: &str = "x-goog-meta-";
5352

5453
static VERSION_MATCH: HeaderName = HeaderName::from_static("x-goog-if-generation-match");
5554

56-
#[derive(Debug, Snafu)]
55+
#[derive(Debug, thiserror::Error)]
5756
enum Error {
58-
#[snafu(display("Error performing list request: {}", source))]
57+
#[error("Error performing list request: {}", source)]
5958
ListRequest { source: crate::client::retry::Error },
6059

61-
#[snafu(display("Error getting list response body: {}", source))]
60+
#[error("Error getting list response body: {}", source)]
6261
ListResponseBody { source: reqwest::Error },
6362

64-
#[snafu(display("Got invalid list response: {}", source))]
63+
#[error("Got invalid list response: {}", source)]
6564
InvalidListResponse { source: quick_xml::de::DeError },
6665

67-
#[snafu(display("Error performing get request {}: {}", path, source))]
66+
#[error("Error performing get request {}: {}", path, source)]
6867
GetRequest {
6968
source: crate::client::retry::Error,
7069
path: String,
7170
},
7271

73-
#[snafu(display("Error performing request {}: {}", path, source))]
72+
#[error("Error performing request {}: {}", path, source)]
7473
Request {
7574
source: crate::client::retry::Error,
7675
path: String,
7776
},
7877

79-
#[snafu(display("Error getting put response body: {}", source))]
78+
#[error("Error getting put response body: {}", source)]
8079
PutResponseBody { source: reqwest::Error },
8180

82-
#[snafu(display("Got invalid put response: {}", source))]
81+
#[error("Got invalid put response: {}", source)]
8382
InvalidPutResponse { source: quick_xml::de::DeError },
8483

85-
#[snafu(display("Unable to extract metadata from headers: {}", source))]
84+
#[error("Unable to extract metadata from headers: {}", source)]
8685
Metadata {
8786
source: crate::client::header::Error,
8887
},
8988

90-
#[snafu(display("Version required for conditional update"))]
89+
#[error("Version required for conditional update")]
9190
MissingVersion,
9291

93-
#[snafu(display("Error performing complete multipart request: {}", source))]
92+
#[error("Error performing complete multipart request: {}", source)]
9493
CompleteMultipartRequest { source: crate::client::retry::Error },
9594

96-
#[snafu(display("Error getting complete multipart response body: {}", source))]
95+
#[error("Error getting complete multipart response body: {}", source)]
9796
CompleteMultipartResponseBody { source: reqwest::Error },
9897

99-
#[snafu(display("Got invalid multipart response: {}", source))]
98+
#[error("Got invalid multipart response: {}", source)]
10099
InvalidMultipartResponse { source: quick_xml::de::DeError },
101100

102-
#[snafu(display("Error signing blob: {}", source))]
101+
#[error("Error signing blob: {}", source)]
103102
SignBlobRequest { source: crate::client::retry::Error },
104103

105-
#[snafu(display("Got invalid signing blob response: {}", source))]
104+
#[error("Got invalid signing blob response: {}", source)]
106105
InvalidSignBlobResponse { source: reqwest::Error },
107106

108-
#[snafu(display("Got invalid signing blob signature: {}", source))]
107+
#[error("Got invalid signing blob signature: {}", source)]
109108
InvalidSignBlobSignature { source: base64::DecodeError },
110109
}
111110

@@ -233,15 +232,17 @@ impl<'a> Request<'a> {
233232
.payload(self.payload)
234233
.send()
235234
.await
236-
.context(RequestSnafu {
237-
path: self.path.as_ref(),
235+
.map_err(|source| {
236+
let path = self.path.as_ref().into();
237+
Error::Request { source, path }
238238
})?;
239239
Ok(resp)
240240
}
241241

242242
async fn do_put(self) -> Result<PutResult> {
243243
let response = self.send().await?;
244-
Ok(get_put_result(response.headers(), VERSION_HEADER).context(MetadataSnafu)?)
244+
Ok(get_put_result(response.headers(), VERSION_HEADER)
245+
.map_err(|source| Error::Metadata { source })?)
245246
}
246247
}
247248

@@ -333,17 +334,17 @@ impl GoogleCloudStorageClient {
333334
.idempotent(true)
334335
.send()
335336
.await
336-
.context(SignBlobRequestSnafu)?;
337+
.map_err(|source| Error::SignBlobRequest { source })?;
337338

338339
//If successful, the signature is returned in the signedBlob field in the response.
339340
let response = response
340341
.json::<SignBlobResponse>()
341342
.await
342-
.context(InvalidSignBlobResponseSnafu)?;
343+
.map_err(|source| Error::InvalidSignBlobResponse { source })?;
343344

344345
let signed_blob = BASE64_STANDARD
345346
.decode(response.signed_blob)
346-
.context(InvalidSignBlobSignatureSnafu)?;
347+
.map_err(|source| Error::InvalidSignBlobSignature { source })?;
347348

348349
Ok(hex_encode(&signed_blob))
349350
}
@@ -386,7 +387,7 @@ impl GoogleCloudStorageClient {
386387
PutMode::Overwrite => builder.idempotent(true),
387388
PutMode::Create => builder.header(&VERSION_MATCH, "0"),
388389
PutMode::Update(v) => {
389-
let etag = v.version.as_ref().context(MissingVersionSnafu)?;
390+
let etag = v.version.as_ref().ok_or(Error::MissingVersion)?;
390391
builder.header(&VERSION_MATCH, etag)
391392
}
392393
};
@@ -440,9 +441,14 @@ impl GoogleCloudStorageClient {
440441
.send()
441442
.await?;
442443

443-
let data = response.bytes().await.context(PutResponseBodySnafu)?;
444+
let data = response
445+
.bytes()
446+
.await
447+
.map_err(|source| Error::PutResponseBody { source })?;
448+
444449
let result: InitiateMultipartUploadResult =
445-
quick_xml::de::from_reader(data.as_ref().reader()).context(InvalidPutResponseSnafu)?;
450+
quick_xml::de::from_reader(data.as_ref().reader())
451+
.map_err(|source| Error::InvalidPutResponse { source })?;
446452

447453
Ok(result.upload_id)
448454
}
@@ -464,8 +470,9 @@ impl GoogleCloudStorageClient {
464470
.query(&[("uploadId", multipart_id)])
465471
.send_retry(&self.config.retry_config)
466472
.await
467-
.context(RequestSnafu {
468-
path: path.as_ref(),
473+
.map_err(|source| {
474+
let path = path.as_ref().into();
475+
Error::Request { source, path }
469476
})?;
470477

471478
Ok(())
@@ -495,7 +502,7 @@ impl GoogleCloudStorageClient {
495502
let credential = self.get_credential().await?;
496503

497504
let data = quick_xml::se::to_string(&upload_info)
498-
.context(InvalidPutResponseSnafu)?
505+
.map_err(|source| Error::InvalidPutResponse { source })?
499506
// We cannot disable the escaping that transforms "/" to "&quote;" :(
500507
// https://github.com/tafia/quick-xml/issues/362
501508
// https://github.com/tafia/quick-xml/issues/350
@@ -511,17 +518,18 @@ impl GoogleCloudStorageClient {
511518
.idempotent(true)
512519
.send()
513520
.await
514-
.context(CompleteMultipartRequestSnafu)?;
521+
.map_err(|source| Error::CompleteMultipartRequest { source })?;
515522

516-
let version = get_version(response.headers(), VERSION_HEADER).context(MetadataSnafu)?;
523+
let version = get_version(response.headers(), VERSION_HEADER)
524+
.map_err(|source| Error::Metadata { source })?;
517525

518526
let data = response
519527
.bytes()
520528
.await
521-
.context(CompleteMultipartResponseBodySnafu)?;
529+
.map_err(|source| Error::CompleteMultipartResponseBody { source })?;
522530

523-
let response: CompleteMultipartUploadResult =
524-
quick_xml::de::from_reader(data.reader()).context(InvalidMultipartResponseSnafu)?;
531+
let response: CompleteMultipartUploadResult = quick_xml::de::from_reader(data.reader())
532+
.map_err(|source| Error::InvalidMultipartResponse { source })?;
525533

526534
Ok(PutResult {
527535
e_tag: Some(response.e_tag),
@@ -612,8 +620,9 @@ impl GetClient for GoogleCloudStorageClient {
612620
.with_get_options(options)
613621
.send_retry(&self.config.retry_config)
614622
.await
615-
.context(GetRequestSnafu {
616-
path: path.as_ref(),
623+
.map_err(|source| {
624+
let path = path.as_ref().into();
625+
Error::GetRequest { source, path }
617626
})?;
618627

619628
Ok(response)
@@ -662,13 +671,13 @@ impl ListClient for GoogleCloudStorageClient {
662671
.bearer_auth(&credential.bearer)
663672
.send_retry(&self.config.retry_config)
664673
.await
665-
.context(ListRequestSnafu)?
674+
.map_err(|source| Error::ListRequest { source })?
666675
.bytes()
667676
.await
668-
.context(ListResponseBodySnafu)?;
677+
.map_err(|source| Error::ListResponseBody { source })?;
669678

670-
let mut response: ListResponse =
671-
quick_xml::de::from_reader(response.reader()).context(InvalidListResponseSnafu)?;
679+
let mut response: ListResponse = quick_xml::de::from_reader(response.reader())
680+
.map_err(|source| Error::InvalidListResponse { source })?;
672681

673682
let token = response.next_continuation_token.take();
674683
Ok((response.try_into()?, token))

0 commit comments

Comments
 (0)