error_ext.rs
1 //! Error handling extensions for more ergonomic error management. 2 //! 3 //! Provides extension traits for Result types that enable logging errors 4 //! while converting to Option, avoiding silent error swallowing. 5 6 use tracing::{error, warn}; 7 8 /// Extension trait for Result types that provides logging variants of `.ok()`. 9 /// 10 /// Instead of silently discarding errors with `.ok()`, use these methods 11 /// to log the error before converting to Option. 12 pub trait ResultExt<T, E: std::fmt::Display> { 13 /// Convert to Option, logging the error at error level if Err. 14 /// 15 /// Use this when the error represents a significant problem that 16 /// should be investigated. 17 fn ok_logged(self, context: &str) -> Option<T>; 18 19 /// Convert to Option, logging the error at warn level if Err. 20 /// 21 /// Use this when the error is expected in some circumstances 22 /// but should still be tracked. 23 fn ok_warn(self, context: &str) -> Option<T>; 24 } 25 26 impl<T, E: std::fmt::Display> ResultExt<T, E> for Result<T, E> { 27 fn ok_logged(self, context: &str) -> Option<T> { 28 match self { 29 Ok(v) => Some(v), 30 Err(e) => { 31 error!(context = %context, error = %e, "Operation failed"); 32 None 33 } 34 } 35 } 36 37 fn ok_warn(self, context: &str) -> Option<T> { 38 match self { 39 Ok(v) => Some(v), 40 Err(e) => { 41 warn!(context = %context, error = %e, "Operation failed (expected in some cases)"); 42 None 43 } 44 } 45 } 46 } 47 48 #[cfg(test)] 49 mod tests { 50 use super::*; 51 52 #[test] 53 fn test_ok_logged_with_ok() { 54 let result: Result<i32, &str> = Ok(42); 55 assert_eq!(result.ok_logged("test"), Some(42)); 56 } 57 58 #[test] 59 fn test_ok_logged_with_err() { 60 let result: Result<i32, &str> = Err("test error"); 61 assert_eq!(result.ok_logged("test context"), None); 62 } 63 64 #[test] 65 fn test_ok_warn_with_ok() { 66 let result: Result<i32, &str> = Ok(42); 67 assert_eq!(result.ok_warn("test"), Some(42)); 68 } 69 70 #[test] 71 fn test_ok_warn_with_err() { 72 let result: Result<i32, &str> = Err("test error"); 73 assert_eq!(result.ok_warn("test context"), None); 74 } 75 }