refactor(errors): surface swallowed errors in auth/issues/space/user/session/storage/email
ZhenYi committed
Modified lib/auth/src/services/login.rs lib/auth/src/services/login.rs +4 −1 View lib/auth/src/services/login.rs
@@ -240,7 +240,10 @@
240240 let device_id = match ua_hash.as_deref() {
241241 Some(hash) => match self.record_device(user.uid, hash, ip_hash.clone()).await {
242242 Ok(id) => id,
243 Err(_) => None,
243 Err(error) => {
244 tracing::warn!(%error, "failed to record device, continuing without it");
245 None
246 }
244247 },
245248 None => None,
246249 };
Modified lib/auth/src/share/crypto.rs lib/auth/src/share/crypto.rs +16 −5 View lib/auth/src/share/crypto.rs
@@ -107,7 +107,10 @@
107107 let nonce = Aes256Gcm::generate_nonce(&mut OsRng);
108108 let ciphertext = cipher
109109 .encrypt(&nonce, plaintext.as_bytes())
110 .map_err(|_| AuthError::Internal("aes encryption failed".to_string()))?;
110 .map_err(|error| {
111 tracing::error!(%error, "aes encryption failed");
112 AuthError::Internal("aes encryption failed".to_string())
113 })?;
111114 let mut output = Vec::with_capacity(nonce.len() + ciphertext.len());
112115 output.extend_from_slice(&nonce);
113116 output.extend_from_slice(&ciphertext);
@@ -117,7 +120,10 @@
117120pub fn aes_decrypt(key_material: &str, stored: &str) -> Result<String, AuthError> {
118121 let bytes = STANDARD
119122 .decode(stored)
120 .map_err(|_| AuthError::Internal("malformed encrypted value".to_string()))?;
123 .map_err(|error| {
124 tracing::error!(%error, "malformed encrypted value");
125 AuthError::Internal("malformed encrypted value".to_string())
126 })?;
121127 if bytes.len() < 12 {
122128 return Err(AuthError::Internal(
123129 "malformed encrypted value".to_string(),
@@ -131,9 +137,14 @@
131137 let cipher = Aes256Gcm::new((&key).into());
132138 let plaintext = cipher
133139 .decrypt(nonce_arr.into(), ciphertext)
134 .map_err(|_| AuthError::Internal("aes decryption failed".to_string()))?;
135 String::from_utf8(plaintext)
136 .map_err(|_| AuthError::Internal("decrypted value is not utf8".to_string()))
140 .map_err(|error| {
141 tracing::error!(%error, "aes decryption failed");
142 AuthError::Internal("aes decryption failed".to_string())
143 })?;
144 String::from_utf8(plaintext).map_err(|error| {
145 tracing::error!(%error, "decrypted value is not utf8");
146 AuthError::Internal("decrypted value is not utf8".to_string())
147 })
137148}
138149
139150fn aes_key(material: &str) -> [u8; 32] {
Modified lib/auth/src/errors.rs lib/auth/src/errors.rs +2 −1 View lib/auth/src/errors.rs
@@ -212,7 +212,8 @@
212212}
213213
214214impl From<(StatusCode, &'static str)> for ApiError {
215 fn from(_error: (StatusCode, &'static str)) -> Self {
215 fn from((status, message): (StatusCode, &'static str)) -> Self {
216 tracing::error!(%status, %message, "unhandled (status, message) converted to 500");
216217 Self::Internal(Self::payload(500, "internal server error"))
217218 }
218219}
No newline at end of file
Modified lib/email/src/service.rs lib/email/src/service.rs +3 −1 View lib/email/src/service.rs
@@ -199,7 +199,9 @@
199199 metadata: Default::default(),
200200 };
201201 if let Some(q) = &self.inner.queue {
202 let _ = q.publish_to(CHANNEL_FAILED, &failed).await;
202 if let Err(err) = q.publish_to(CHANNEL_FAILED, &failed).await {
203 warn!(error = %err, "failed to publish EmailFailed event");
204 }
203205 }
204206 }
205207 }
Modified lib/issues/src/errors.rs lib/issues/src/errors.rs +2 −1 View lib/issues/src/errors.rs
@@ -190,7 +190,8 @@
190190}
191191
192192impl From<(StatusCode, &'static str)> for ApiError {
193 fn from(_error: (StatusCode, &'static str)) -> Self {
193 fn from((status, message): (StatusCode, &'static str)) -> Self {
194 tracing::error!(%status, %message, "unhandled (status, message) converted to 500");
194195 Self::Internal(Self::payload(500, "internal server error"))
195196 }
196197}
Modified lib/session/src/error.rs lib/session/src/error.rs +4 −2 View lib/session/src/error.rs
@@ -37,8 +37,10 @@
3737 match self {
3838 Self::Unauthorized => AppResponseData::<NoData>::err(401, "unauthorized")
3939 .into_response(),
40 Self::Database(_) => AppResponseData::<NoData>::err(500, "internal error")
41 .into_response(),
40 Self::Database(err) => {
41 tracing::error!(error = %err, "session store failure");
42 AppResponseData::<NoData>::err(500, "internal error").into_response()
43 }
4244 }
4345 }
4446}
No newline at end of file
Modified lib/space/src/services/avatar.rs lib/space/src/services/avatar.rs +11 −4 View lib/space/src/services/avatar.rs
@@ -129,11 +129,14 @@
129129 "bytes": bytes.len(),
130130 "uploaded_at": now,
131131 });
132 let _ = self
132 if let Err(error) = self
133133 .storage()
134134 .client()
135135 .put_with_content_type(&meta_key, meta.to_string().as_bytes(), "application/json")
136 .await;
136 .await
137 {
138 tracing::warn!(%error, "failed to write space avatar meta json");
139 }
137140
138141 Ok(SpaceAvatarDto {
139142 space_id,
@@ -166,9 +169,13 @@
166169 if let Some(url) = old_url
167170 && let Some(key) = url.strip_prefix("storage://")
168171 {
169 let _ = self.storage().client().delete(key).await;
172 if let Err(error) = self.storage().client().delete(key).await {
173 tracing::warn!(%error, "failed to delete old space avatar object");
174 }
170175 let meta_key = format!("{SPACE_AVATAR_PREFIX}/{}.meta.json", space_id);
171 let _ = self.storage().client().delete(&meta_key).await;
176 if let Err(error) = self.storage().client().delete(&meta_key).await {
177 tracing::warn!(%error, "failed to delete old space avatar meta json");
178 }
172179 }
173180 Ok(())
174181 }
Modified lib/space/src/services/images.rs lib/space/src/services/images.rs +11 −4 View lib/space/src/services/images.rs
@@ -150,11 +150,14 @@
150150 "bytes": bytes.len(),
151151 "uploaded_at": now,
152152 });
153 let _ = self
153 if let Err(error) = self
154154 .storage()
155155 .client()
156156 .put_with_content_type(&meta_key, meta.to_string().as_bytes(), "application/json")
157 .await;
157 .await
158 {
159 tracing::warn!(%error, "failed to write space image meta json");
160 }
158161
159162 Ok(SpaceImageDto {
160163 space_id,
@@ -211,13 +214,17 @@
211214 if let Some(url) = old_url
212215 && let Some(key) = url.strip_prefix("storage://")
213216 {
214 let _ = self.storage().client().delete(key).await;
217 if let Err(error) = self.storage().client().delete(key).await {
218 tracing::warn!(%error, "failed to delete old space image object");
219 }
215220 let meta_key = format!(
216221 "{SPACE_IMAGE_PREFIX}/{}/{}.meta.json",
217222 space_id,
218223 kind.as_str()
219224 );
220 let _ = self.storage().client().delete(&meta_key).await;
225 if let Err(error) = self.storage().client().delete(&meta_key).await {
226 tracing::warn!(%error, "failed to delete old space image meta json");
227 }
221228 }
222229 Ok(())
223230 }
Modified lib/space/src/errors.rs lib/space/src/errors.rs +2 −1 View lib/space/src/errors.rs
@@ -183,7 +183,8 @@
183183}
184184
185185impl From<(StatusCode, &'static str)> for ApiError {
186 fn from(_error: (StatusCode, &'static str)) -> Self {
186 fn from((status, message): (StatusCode, &'static str)) -> Self {
187 tracing::error!(%status, %message, "unhandled (status, message) converted to 500");
187188 Self::Internal(Self::payload(500, "internal server error"))
188189 }
189190}
Modified lib/storage/src/s3.rs lib/storage/src/s3.rs +3 −1 View lib/storage/src/s3.rs
@@ -437,7 +437,9 @@
437437/// Fire-and-forget multipart abort (errors are intentionally swallowed: the
438438/// original failure is what the caller cares about).
439439async fn abort_upload(bucket: &Bucket, path: &str, upload_id: &str) {
440 let _ = bucket.abort_upload(path, upload_id).await;
440 if let Err(error) = bucket.abort_upload(path, upload_id).await {
441 tracing::warn!(%error, "failed to abort multipart upload");
442 }
441443}
442444
443445struct CountingWriter<'a, W> {
Modified lib/storage/Cargo.toml lib/storage/Cargo.toml +2 −1 View lib/storage/Cargo.toml
@@ -9,4 +9,5 @@
99tokio = { workspace = true, features = ["macros", "rt", "io-util"] }
1010http = { workspace = true }
1111futures = { workspace = true }
12bytes = { workspace = true }
No newline at end of file
12bytes = { workspace = true }
13tracing = { workspace = true }
No newline at end of file
Modified lib/user/src/services/avatar.rs lib/user/src/services/avatar.rs +20 −8 View lib/user/src/services/avatar.rs
@@ -121,12 +121,20 @@
121121 "bytes": bytes.len(),
122122 "uploaded_at": now,
123123 });
124 if let Ok(meta_bytes) = serde_json::to_vec(&meta) {
125 let _ = self
126 .storage()
127 .client()
128 .put_with_content_type(&meta_key, &meta_bytes, "application/json")
129 .await;
124match serde_json::to_vec(&meta) {
125 Ok(meta_bytes) => {
126 if let Err(error) = self
127 .storage()
128 .client()
129 .put_with_content_type(&meta_key, &meta_bytes, "application/json")
130 .await
131 {
132 tracing::warn!(%error, "failed to write user avatar meta json");
133 }
134 }
135 Err(error) => {
136 tracing::warn!(%error, "failed to serialize user avatar meta json");
137 }
130138 }
131139
132140 Ok(AvatarDto {
@@ -156,9 +164,13 @@
156164 .trim_start_matches(AVATAR_PREFIX)
157165 .trim_start_matches('/');
158166 let key = format!("{AVATAR_PREFIX}/{rel}");
159 let _ = self.storage().client().delete(&key).await;
167 if let Err(error) = self.storage().client().delete(&key).await {
168 tracing::warn!(%error, "failed to delete old user avatar object");
169 }
160170 let meta_key = format!("{AVATAR_PREFIX}/{uid}.meta.json");
161 let _ = self.storage().client().delete(&meta_key).await;
171 if let Err(error) = self.storage().client().delete(&meta_key).await {
172 tracing::warn!(%error, "failed to delete old user avatar meta json");
173 }
162174 }
163175 Ok(())
164176 }
Modified lib/user/src/errors.rs lib/user/src/errors.rs +2 −1 View lib/user/src/errors.rs
@@ -189,7 +189,8 @@
189189}
190190
191191impl From<(StatusCode, &'static str)> for ApiError {
192 fn from(_error: (StatusCode, &'static str)) -> Self {
192 fn from((status, message): (StatusCode, &'static str)) -> Self {
193 tracing::error!(%status, %message, "unhandled (status, message) converted to 500");
193194 Self::Internal(Self::payload(500, "internal server error"))
194195 }
195196}