s3_algo/
err.rs

1use aws_sdk_s3::error::SdkError;
2use aws_sdk_s3::operation::copy_object::CopyObjectError;
3use aws_sdk_s3::operation::delete_object::DeleteObjectError;
4use aws_sdk_s3::operation::delete_objects::DeleteObjectsError;
5use aws_sdk_s3::operation::get_object::GetObjectError;
6use aws_sdk_s3::operation::list_objects_v2::ListObjectsV2Error;
7use aws_sdk_s3::operation::put_object::PutObjectError;
8use aws_sdk_s3::primitives::ByteStreamError;
9use snafu::{Backtrace, Snafu};
10use std::io;
11
12#[derive(Snafu, Debug)]
13#[snafu(visibility = "pub")]
14pub enum Error {
15    #[snafu(display("Io error: {}: {}", description, source))]
16    Io {
17        source: io::Error,
18        description: String,
19        backtrace: Backtrace,
20    },
21    /// Error originating from tokio::Delay
22    #[snafu(display("Tokio timer error: {}", source))]
23    Delay {
24        source: tokio::time::error::Error,
25        backtrace: Backtrace,
26    },
27    #[snafu(display("S3 operation timed out"))]
28    Timeout {
29        source: tokio::time::error::Elapsed,
30    },
31    #[snafu(display("Error listing objects in S3: {:?}", source))]
32    ListObjectsV2 {
33        source: SdkError<ListObjectsV2Error>,
34    },
35    #[snafu(display("Error deleting objects in S3: {:?}", source))]
36    DeleteObjects {
37        source: SdkError<DeleteObjectsError>,
38    },
39    DeleteObject {
40        source: SdkError<DeleteObjectError>,
41    },
42    CopyObject {
43        source: SdkError<CopyObjectError>,
44    },
45    #[snafu(display("GetObject s3://{}/{}: {:#?}", bucket, key, source))]
46    GetObject {
47        key: String,
48        bucket: String,
49        source: SdkError<GetObjectError>,
50    },
51    #[snafu(display("IO error: {}", source))]
52    TokioIo {
53        source: tokio::io::Error,
54    },
55    AnyError {
56        source: Box<dyn std::error::Error + Send + Sync>,
57    },
58
59    #[snafu(display("Downloading objects: missing key or size property"))]
60    MissingKeyOrSize,
61    #[snafu(display("Downloading objects: missing content_length property"))]
62    MissingContentLength,
63
64    // AWS SDK Errors
65    #[snafu(display("S3 'put object' error on key '{}': {}", key, source))]
66    PutObject {
67        source: SdkError<PutObjectError>,
68        key: String,
69        backtrace: Backtrace,
70    },
71
72    #[snafu(display("Error listing objects in S3: {:?}", source))]
73    NewListObjectsV2 {
74        source: SdkError<ListObjectsV2Error>,
75    },
76
77    #[snafu(display("Error deleting objects in S3: {:?}", source))]
78    NewDeleteObjects {
79        source: SdkError<DeleteObjectsError>,
80    },
81    NewDeleteObject {
82        source: SdkError<DeleteObjectError>,
83    },
84    NewCopyObject {
85        source: SdkError<CopyObjectError>,
86    },
87    #[snafu(display("GetObject s3://{}/{}: {:#?}", bucket, key, source))]
88    NewGetObject {
89        key: String,
90        bucket: String,
91        source: SdkError<GetObjectError>,
92    },
93}
94
95impl<T> From<SdkError<T>> for Error
96where
97    T: std::error::Error + Send + Sync + 'static,
98{
99    fn from(err: SdkError<T>) -> Self {
100        Self::AnyError {
101            source: Box::new(err),
102        }
103    }
104}
105
106impl From<ByteStreamError> for Error {
107    fn from(err: ByteStreamError) -> Self {
108        Self::AnyError {
109            source: Box::new(err),
110        }
111    }
112}
113
114#[cfg(test)]
115mod test {
116    use super::*;
117    use snafu::GenerateBacktrace;
118    #[test]
119    fn error_traits() {
120        fn foo<T: Send>(_: T) {}
121        foo(Error::Io {
122            source: io::Error::from_raw_os_error(1),
123            description: "hello".into(),
124            backtrace: Backtrace::generate(),
125        });
126    }
127}