xtax_blob_storage/
error.rs1use std::fmt;
2
3#[derive(Debug, Clone)]
5pub enum PerKeyError {
6 NotFound,
12
13 PermissionDenied(String),
15
16 Unknown { message: String },
19}
20
21impl fmt::Display for PerKeyError {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 match self {
24 PerKeyError::NotFound => write!(f, "not found"),
25 PerKeyError::PermissionDenied(msg) => write!(f, "permission denied: {msg}"),
26 PerKeyError::Unknown { message } => write!(f, "unknown: {message}"),
27 }
28 }
29}
30
31#[derive(Debug, Clone)]
33pub struct KeyError {
34 pub key: String,
36 pub error: PerKeyError,
38}
39
40#[derive(Debug, Clone)]
45pub struct BatchError {
46 pub succeeded: Vec<String>,
48 pub errors: Vec<KeyError>,
50}
51
52impl BatchError {
53 pub fn total_count(&self) -> usize {
55 self.succeeded.len() + self.errors.len()
56 }
57
58 pub fn failed_count(&self) -> usize {
60 self.errors.len()
61 }
62}
63
64impl fmt::Display for BatchError {
65 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66 write!(
67 f,
68 "batch operation failed: {} keys failed ({} succeeded, {} total)",
69 self.failed_count(),
70 self.succeeded.len(),
71 self.total_count(),
72 )
73 }
74}
75
76impl std::error::Error for BatchError {}
77
78#[derive(Debug, thiserror::Error)]
80pub enum BlobStorageError {
81 #[error("blob not found: {0}")]
83 NotFound(String),
84
85 #[error("blob already exists: {0}")]
87 AlreadyExists(String),
88
89 #[error("operation not supported: {0}")]
91 NotSupported(String),
92
93 #[error("backend misconfigured: {0}")]
99 BackendMisconfigured(String),
100
101 #[error("invalid input: {0}")]
103 InvalidInput(String),
104
105 #[error("storage error: {message}")]
108 Storage {
109 message: String,
110 #[source]
111 source: Option<Box<dyn std::error::Error + Send + Sync + 'static>>,
112 },
113
114 #[error("encryption error: {message}")]
116 Encryption {
117 message: String,
118 #[source]
119 source: Option<Box<dyn std::error::Error + Send + Sync + 'static>>,
120 },
121
122 #[error("permission denied: {0}")]
124 PermissionDenied(String),
125
126 #[error("batch error: {0}")]
129 Batch(#[from] BatchError),
130}
131
132pub type Result<T> = std::result::Result<T, BlobStorageError>;
133
134impl From<std::io::Error> for BlobStorageError {
135 fn from(e: std::io::Error) -> Self {
136 Self::Storage {
137 message: "I/O error".to_string(),
138 source: Some(Box::new(e)),
139 }
140 }
141}
142
143impl From<String> for BlobStorageError {
144 fn from(msg: String) -> Self {
145 Self::Storage {
146 message: msg,
147 source: None,
148 }
149 }
150}
151
152impl From<&str> for BlobStorageError {
153 fn from(msg: &str) -> Self {
154 Self::Storage {
155 message: msg.to_string(),
156 source: None,
157 }
158 }
159}
160
161impl From<xtax_encryption::EncryptionError> for BlobStorageError {
162 fn from(e: xtax_encryption::EncryptionError) -> Self {
163 Self::Encryption {
164 message: e.to_string(),
165 source: Some(Box::new(e)),
166 }
167 }
168}