Skip to content

Commit 2807216

Browse files
Add bucket and other info to AWS errors (#1123)
* Add bucket and other info to AWS errors When you have multiple file_info_pollers running and one of them may be misconfigured, it is difficult to tell from (usually) the `ListObjectsV2Error` which poller is failing. This PR adds the bucket and file key or prefix for the operation that was being attempted. Adding the extra information bumps the Err size to 216 bytes, so we box it to keep from tripping clippy’s `result_large_err` lint. * tonic has been upgraded, remove clippy.toml We no longer have to deal with tonic’s large err variants in file-store. So we can remove this allowance. * Box ClientError for large variant Even though this will go away soon
1 parent 2d4f13a commit 2807216

4 files changed

Lines changed: 111 additions & 39 deletions

File tree

clippy.toml

Lines changed: 0 additions & 5 deletions
This file was deleted.

file_store/src/error.rs

Lines changed: 83 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub enum Error {
2323
FileInfo(#[from] FileInfoError),
2424

2525
#[error("aws error: {0}")]
26-
Aws(#[from] AwsError),
26+
Aws(#[from] Box<AwsError>),
2727

2828
#[error("channel error: {0}")]
2929
Channel(#[from] ChannelError),
@@ -90,6 +90,8 @@ impl ChannelError {
9090
}
9191

9292
mod aws_error {
93+
use std::path::PathBuf;
94+
9395
use super::Error;
9496

9597
use aws_sdk_s3::error::SdkError;
@@ -103,41 +105,101 @@ mod aws_error {
103105

104106
#[derive(thiserror::Error, Debug)]
105107
pub enum AwsError {
106-
#[error("put_object: {0}")]
107-
PutObject(PutObjectError),
108+
#[error("put_object ({bucket}::{file_path}): {source}")]
109+
PutObject {
110+
source: PutObjectError,
111+
bucket: String,
112+
file_path: PathBuf,
113+
},
108114

109-
#[error("pub_object_byte_stream: {0}")]
110-
PubObjectByteStream(ByteStreamError),
115+
#[error("pub_object_byte_stream ({bucket}::{file_path}): {source}")]
116+
PubObjectByteStream {
117+
source: ByteStreamError,
118+
bucket: String,
119+
file_path: PathBuf,
120+
},
111121

112-
#[error("delete_object: {0}")]
113-
DeleteObject(DeleteObjectError),
122+
#[error("delete_object ({bucket}::{key}): {source}")]
123+
DeleteObject {
124+
source: DeleteObjectError,
125+
bucket: String,
126+
key: String,
127+
},
114128

115-
#[error("get_object: {0}")]
116-
GetObject(GetObjectError),
129+
#[error("get_object ({bucket}::{key}): {source}")]
130+
GetObject {
131+
source: GetObjectError,
132+
bucket: String,
133+
key: String,
134+
},
117135

118-
#[error("list_object: {0}")]
119-
ListObject(ListObjectsV2Error),
136+
#[error("list_object ({bucket}::{prefix}): {source}")]
137+
ListObject {
138+
source: ListObjectsV2Error,
139+
bucket: String,
140+
prefix: String,
141+
},
120142
}
121143

122144
impl AwsError {
123-
pub fn put_object_error(err: SdkError<PutObjectError>) -> Error {
124-
Error::Aws(Self::PutObject(err.into_service_error()))
145+
pub fn put_object_error(
146+
err: SdkError<PutObjectError>,
147+
bucket: &str,
148+
file_path: impl Into<PathBuf>,
149+
) -> Error {
150+
Error::Aws(Box::new(Self::PutObject {
151+
source: err.into_service_error(),
152+
bucket: bucket.into(),
153+
file_path: file_path.into(),
154+
}))
125155
}
126156

127-
pub fn pub_object_byte_stream_error(err: ByteStreamError) -> Error {
128-
Error::Aws(Self::PubObjectByteStream(err))
157+
pub fn pub_object_byte_stream_error(
158+
err: ByteStreamError,
159+
bucket: impl Into<String>,
160+
file_path: impl Into<PathBuf>,
161+
) -> Error {
162+
Error::Aws(Box::new(Self::PubObjectByteStream {
163+
source: err,
164+
bucket: bucket.into(),
165+
file_path: file_path.into(),
166+
}))
129167
}
130168

131-
pub fn delete_object_error(err: SdkError<DeleteObjectError>) -> Error {
132-
Error::Aws(Self::DeleteObject(err.into_service_error()))
169+
pub fn delete_object_error(
170+
err: SdkError<DeleteObjectError>,
171+
bucket: impl Into<String>,
172+
key: impl Into<String>,
173+
) -> Error {
174+
Error::Aws(Box::new(Self::DeleteObject {
175+
source: err.into_service_error(),
176+
bucket: bucket.into(),
177+
key: key.into(),
178+
}))
133179
}
134180

135-
pub fn get_object_error(err: SdkError<GetObjectError>) -> Error {
136-
Error::Aws(Self::GetObject(err.into_service_error()))
181+
pub fn get_object_error(
182+
err: SdkError<GetObjectError>,
183+
bucket: impl Into<String>,
184+
key: impl Into<String>,
185+
) -> Error {
186+
Error::Aws(Box::new(Self::GetObject {
187+
source: err.into_service_error(),
188+
bucket: bucket.into(),
189+
key: key.into(),
190+
}))
137191
}
138192

139-
pub fn list_object_error(err: SdkError<ListObjectsV2Error>) -> Error {
140-
Error::Aws(Self::ListObject(err.into_service_error()))
193+
pub fn list_object_error(
194+
err: SdkError<ListObjectsV2Error>,
195+
bucket: &str,
196+
prefix: &str,
197+
) -> Error {
198+
Error::Aws(Box::new(Self::ListObject {
199+
source: err.into_service_error(),
200+
bucket: bucket.to_string(),
201+
prefix: prefix.to_string(),
202+
}))
141203
}
142204
}
143205
}

file_store/src/lib.rs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -134,17 +134,18 @@ fn _list_files(
134134
after: Option<DateTime<Utc>>,
135135
) -> FileInfoStream {
136136
let prefix = prefix.into();
137+
let bucket = bucket.into();
137138

138139
client
139140
.list_objects_v2()
140-
.bucket(bucket)
141+
.bucket(&bucket)
141142
.prefix(&prefix)
142143
.set_start_after(after.map(|dt| FileInfo::from_maybe_dotted_prefix(&prefix, dt).into()))
143144
.into_paginator()
144145
.send()
145146
.into_stream_03x()
146147
.map_ok(|page| stream::iter(page.contents.unwrap_or_default()).map(Ok))
147-
.map_err(AwsError::list_object_error)
148+
.map_err(move |err| AwsError::list_object_error(err, &bucket, &prefix))
148149
.try_flatten()
149150
.try_filter_map(|file| {
150151
future::ready(FileInfo::try_from(&file).map(Some).map_err(Error::from))
@@ -169,21 +170,23 @@ where
169170
}
170171

171172
pub async fn put_file(client: &Client, bucket: impl Into<String>, file: &Path) -> Result {
173+
let bucket: String = bucket.into();
174+
172175
let byte_stream = ByteStream::from_path(&file)
173-
.map_err(AwsError::pub_object_byte_stream_error)
176+
.map_err(|err| AwsError::pub_object_byte_stream_error(err, &bucket, file))
174177
.await?;
175178

176179
poc_metrics::record_duration!(
177180
"file_store_put_duration",
178181
client
179182
.put_object()
180-
.bucket(bucket)
183+
.bucket(&bucket)
181184
.key(file.file_name().map(|name| name.to_string_lossy()).unwrap())
182185
.body(byte_stream)
183186
.content_type("application/octet-stream")
184187
.send()
185188
.map_ok(|_| ())
186-
.map_err(AwsError::put_object_error)
189+
.map_err(|err| AwsError::put_object_error(err, &bucket, file))
187190
.await
188191
)
189192
}
@@ -193,15 +196,18 @@ pub async fn remove_file(
193196
bucket: impl Into<String>,
194197
key: impl Into<String>,
195198
) -> Result {
199+
let bucket = bucket.into();
200+
let key = key.into();
201+
196202
poc_metrics::record_duration!(
197203
"file_store_remove_duration",
198204
client
199205
.delete_object()
200-
.bucket(bucket)
201-
.key(key)
206+
.bucket(&bucket)
207+
.key(&key)
202208
.send()
203209
.map_ok(|_| ())
204-
.map_err(AwsError::delete_object_error)
210+
.map_err(|err| AwsError::delete_object_error(err, bucket, key))
205211
.await
206212
)
207213
}
@@ -288,13 +294,16 @@ async fn get_byte_stream(
288294
bucket: impl Into<String>,
289295
key: impl Into<String>,
290296
) -> Result<ByteStream> {
297+
let bucket = bucket.into();
298+
let key = key.into();
299+
291300
client
292301
.get_object()
293-
.bucket(bucket)
294-
.key(key)
302+
.bucket(&bucket)
303+
.key(&key)
295304
.send()
296305
.map_ok(|output| output.body)
297-
.map_err(AwsError::get_object_error)
306+
.map_err(|err| AwsError::get_object_error(err, bucket, key))
298307
.fuse()
299308
.await
300309
}

iot_verifier/src/region_cache.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,13 @@ pub enum RegionCacheError {
2626
#[error("region not found: {0}")]
2727
RegionNotFound(ProtoRegion),
2828
#[error("error querying gateway api")]
29-
GatewayApiError(ClientError),
29+
GatewayApiError(Box<ClientError>),
30+
}
31+
32+
impl From<ClientError> for RegionCacheError {
33+
fn from(err: ClientError) -> Self {
34+
Self::GatewayApiError(Box::new(err))
35+
}
3036
}
3137

3238
impl<G> RegionCache<G>
@@ -62,7 +68,7 @@ where
6268
.await;
6369
Ok(res)
6470
}
65-
Err(err) => Err(RegionCacheError::GatewayApiError(err)),
71+
Err(err) => Err(err)?,
6672
},
6773
}
6874
}

0 commit comments

Comments
 (0)