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 #[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 #[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}