1use rsb_derive::Builder;
2use std::error::Error;
3use std::fmt::Display;
4use std::fmt::Formatter;
5
6pub type BoxedError = Box<dyn std::error::Error + Send + Sync>;
7
8#[cfg(feature = "serde")]
9use serde::{Deserialize, Serialize};
10
11#[derive(Debug)]
12pub enum SecretVaultError {
13 SystemError(SecretVaultSystemError),
14 DataNotFoundError(SecretVaultDataNotFoundError),
15 InvalidParametersError(SecretVaultInvalidParametersError),
16 NetworkError(SecretVaultNetworkError),
17 EncryptionError(SecretVaultEncryptionError),
18 SecretsSourceError(SecretsSourceError),
19}
20
21impl Display for SecretVaultError {
22 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
23 match *self {
24 SecretVaultError::SystemError(ref err) => err.fmt(f),
25 SecretVaultError::DataNotFoundError(ref err) => err.fmt(f),
26 SecretVaultError::InvalidParametersError(ref err) => err.fmt(f),
27 SecretVaultError::NetworkError(ref err) => err.fmt(f),
28 SecretVaultError::EncryptionError(ref err) => err.fmt(f),
29 SecretVaultError::SecretsSourceError(ref err) => err.fmt(f),
30 }
31 }
32}
33
34impl std::error::Error for SecretVaultError {
35 fn source(&self) -> Option<&(dyn Error + 'static)> {
36 match *self {
37 SecretVaultError::SystemError(ref err) => Some(err),
38 SecretVaultError::DataNotFoundError(ref err) => Some(err),
39 SecretVaultError::InvalidParametersError(ref err) => Some(err),
40 SecretVaultError::NetworkError(ref err) => Some(err),
41 SecretVaultError::EncryptionError(ref err) => Some(err),
42 SecretVaultError::SecretsSourceError(ref err) => Some(err),
43 }
44 }
45}
46
47#[derive(Debug, Eq, PartialEq, Clone, Builder)]
48#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
49pub struct SecretVaultErrorPublicGenericDetails {
50 pub code: String,
51}
52
53#[derive(Debug, Eq, PartialEq, Clone, Builder)]
54pub struct SecretVaultSystemError {
55 pub public: SecretVaultErrorPublicGenericDetails,
56 pub message: String,
57}
58
59impl Display for SecretVaultSystemError {
60 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
61 write!(
62 f,
63 "SecretVault system/internal error: {:?} / {}",
64 self.public, self.message
65 )
66 }
67}
68
69impl std::error::Error for SecretVaultSystemError {}
70
71#[derive(Debug, Clone, Builder)]
72pub struct SecretVaultDatabaseError {
73 pub public: SecretVaultErrorPublicGenericDetails,
74 pub details: String,
75 pub retry_possible: bool,
76}
77
78impl Display for SecretVaultDatabaseError {
79 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
80 write!(
81 f,
82 "Database general error occurred: {:?} / {}",
83 self.public, self.details
84 )
85 }
86}
87
88impl std::error::Error for SecretVaultDatabaseError {}
89
90#[derive(Debug, Clone, Builder)]
91pub struct SecretVaultDataConflictError {
92 pub public: SecretVaultErrorPublicGenericDetails,
93 pub details: String,
94}
95
96impl Display for SecretVaultDataConflictError {
97 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
98 write!(
99 f,
100 "Database conflict error occurred: {:?} / {}",
101 self.public, self.details
102 )
103 }
104}
105
106impl std::error::Error for SecretVaultDataConflictError {}
107
108#[derive(Debug, Clone, Builder)]
109pub struct SecretVaultDataNotFoundError {
110 pub public: SecretVaultErrorPublicGenericDetails,
111 pub data_detail_message: String,
112}
113
114impl Display for SecretVaultDataNotFoundError {
115 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
116 write!(f, "Data not found error occurred: {:?}", self.public)
117 }
118}
119
120impl std::error::Error for SecretVaultDataNotFoundError {}
121
122#[derive(Debug, Eq, PartialEq, Clone, Builder)]
123#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
124pub struct SecretVaultInvalidParametersPublicDetails {
125 pub field: String,
126 pub error: String,
127}
128
129#[derive(Debug, Clone, Builder)]
130pub struct SecretVaultInvalidParametersError {
131 pub public: SecretVaultInvalidParametersPublicDetails,
132}
133
134impl Display for SecretVaultInvalidParametersError {
135 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
136 write!(f, "Data not found error occurred: {:?}", self.public)
137 }
138}
139
140impl std::error::Error for SecretVaultInvalidParametersError {}
141
142#[derive(Debug, Eq, PartialEq, Clone, Builder)]
143#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
144pub struct SecretVaultInvalidJsonErrorPublicDetails {
145 pub code: String,
146}
147
148#[derive(Debug, Eq, PartialEq, Clone, Builder)]
149pub struct SecretVaultNetworkError {
150 pub public: SecretVaultErrorPublicGenericDetails,
151 pub message: String,
152}
153
154impl Display for SecretVaultNetworkError {
155 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
156 write!(f, "Network error: {:?} / {}", self.public, self.message)
157 }
158}
159
160impl std::error::Error for SecretVaultNetworkError {}
161
162#[derive(Debug, Eq, PartialEq, Clone, Builder)]
163pub struct SecretVaultEncryptionError {
164 pub public: SecretVaultErrorPublicGenericDetails,
165 pub message: String,
166}
167
168impl SecretVaultEncryptionError {
169 pub fn create(code: &str, message: &str) -> SecretVaultError {
170 SecretVaultError::EncryptionError(SecretVaultEncryptionError::new(
171 SecretVaultErrorPublicGenericDetails::new(code.to_string()),
172 message.to_string(),
173 ))
174 }
175}
176
177impl Display for SecretVaultEncryptionError {
178 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
179 write!(
180 f,
181 "SecretVault encryption error: {:?} / {}",
182 self.public, self.message
183 )
184 }
185}
186
187impl std::error::Error for SecretVaultEncryptionError {}
188
189#[derive(Debug, Builder)]
190pub struct SecretsSourceError {
191 pub public: SecretVaultErrorPublicGenericDetails,
192 pub message: String,
193 pub root_cause: Option<BoxedError>,
194}
195
196impl Display for SecretsSourceError {
197 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
198 write!(
199 f,
200 "SecretVault source error: {:?} / {}",
201 self.public, self.message
202 )
203 }
204}
205
206impl std::error::Error for SecretsSourceError {}
207
208#[cfg(feature = "gcp-base")]
209impl From<gcloud_sdk::error::Error> for SecretVaultError {
210 fn from(e: gcloud_sdk::error::Error) -> Self {
211 SecretVaultError::SecretsSourceError(
212 SecretsSourceError::new(
213 SecretVaultErrorPublicGenericDetails::new(format!("{:?}", e.kind())),
214 format!("GCloud system error: {e}"),
215 )
216 .with_root_cause(Box::new(e)),
217 )
218 }
219}
220
221#[cfg(feature = "gcp-base")]
222impl From<gcloud_sdk::tonic::Status> for SecretVaultError {
223 fn from(status: gcloud_sdk::tonic::Status) -> Self {
224 match status.code() {
225 gcloud_sdk::tonic::Code::NotFound => {
226 SecretVaultError::DataNotFoundError(SecretVaultDataNotFoundError::new(
227 SecretVaultErrorPublicGenericDetails::new(format!("{:?}", status.code())),
228 format!("{status}"),
229 ))
230 }
231 gcloud_sdk::tonic::Code::Aborted
232 | gcloud_sdk::tonic::Code::Cancelled
233 | gcloud_sdk::tonic::Code::Unavailable
234 | gcloud_sdk::tonic::Code::ResourceExhausted => {
235 SecretVaultError::NetworkError(SecretVaultNetworkError::new(
236 SecretVaultErrorPublicGenericDetails::new(format!("{:?}", status.code())),
237 format!("{status}"),
238 ))
239 }
240 _ => SecretVaultError::NetworkError(SecretVaultNetworkError::new(
241 SecretVaultErrorPublicGenericDetails::new(format!("{:?}", status.code())),
242 format!("{status}"),
243 )),
244 }
245 }
246}
247
248#[cfg(feature = "aws-secretmanager")]
249impl<E: Display + Error + Sync + Send + 'static, R: std::fmt::Debug + Sync + Send + 'static>
250 From<aws_sdk_secretsmanager::error::SdkError<E, R>> for SecretVaultError
251{
252 fn from(e: aws_sdk_secretsmanager::error::SdkError<E, R>) -> Self {
253 SecretVaultError::SecretsSourceError(
254 SecretsSourceError::new(
255 SecretVaultErrorPublicGenericDetails::new(format!("{e}")),
256 format!("AWS error: {e}"),
257 )
258 .with_root_cause(Box::new(e)),
259 )
260 }
261}
262
263#[cfg(not(feature = "aws-secretmanager"))]
264#[cfg(feature = "aws-kms-encryption")]
265impl<E: Display + Error + Sync + Send + 'static, R: std::fmt::Debug + Sync + Send + 'static>
266 From<aws_sdk_kms::error::SdkError<E, R>> for SecretVaultError
267{
268 fn from(e: aws_sdk_kms::error::SdkError<E, R>) -> Self {
269 SecretVaultError::SecretsSourceError(
270 SecretsSourceError::new(
271 SecretVaultErrorPublicGenericDetails::new(format!("{e}")),
272 format!("AWS KMS error: {e}"),
273 )
274 .with_root_cause(Box::new(e)),
275 )
276 }
277}
278
279#[cfg(any(feature = "kms", feature = "ring-aead-encryption"))]
280impl From<kms_aead::errors::KmsAeadError> for SecretVaultError {
281 fn from(e: kms_aead::errors::KmsAeadError) -> Self {
282 SecretVaultError::EncryptionError(SecretVaultEncryptionError::new(
283 SecretVaultErrorPublicGenericDetails::new(format!("{e:?}")),
284 format!("KMS error: {e}"),
285 ))
286 }
287}