mod utils; use std::{fmt::Display, ops::Deref}; use errify::errify_with; use utils::*; #[test] fn simple_closure() { #[errify_with(|| format!("closure {arg}"))] fn func(arg: i32) -> Result { Err(ErrorWithContext::new(arg)) } let err = func(1).unwrap_err(); assert_eq!(err.msg.deref(), "1"); assert_eq!(err.cx.as_deref(), Some("closure 1")); } #[test] fn simple_fn() { fn context() -> impl Display { ContextExpr::new(2) } #[errify_with(context)] fn func(arg: i32) -> Result { Err(ErrorWithContext::new(arg)) } let err = func(1).unwrap_err(); assert_eq!(err.msg.deref(), "1"); assert_eq!(err.cx.as_deref(), Some("ContextExpr(2)")); } #[tokio::test] async fn async_closure() { #[errify_with(|| format!("closure {arg}"))] async fn func(arg: i32) -> Result { Err(ErrorWithContext::new(arg)) } let err = func(1).await.unwrap_err(); assert_eq!(err.msg.deref(), "1"); assert_eq!(err.cx.as_deref(), Some("closure 1")); } #[tokio::test] async fn async_fn() { fn context() -> impl Display { ContextExpr::new(2) } #[errify_with(context)] async fn func(arg: i32) -> Result { Err(ErrorWithContext::new(arg)) } let err = func(1).await.unwrap_err(); assert_eq!(err.msg.deref(), "1"); assert_eq!(err.cx.as_deref(), Some("ContextExpr(2)")); } #[test] fn unsafe_closure() { #[errify_with(|| format!("closure {arg}"))] unsafe fn func(arg: i32) -> Result { Err(ErrorWithContext::new(arg)) } let err = unsafe { func(1).unwrap_err() }; assert_eq!(err.msg.deref(), "1"); assert_eq!(err.cx.as_deref(), Some("closure 1")); } #[test] fn unsafe_fn() { fn context() -> impl Display { ContextExpr::new(2) } #[errify_with(context)] unsafe fn func(arg: i32) -> Result { Err(ErrorWithContext::new(arg)) } let err = unsafe { func(1).unwrap_err() }; assert_eq!(err.msg.deref(), "1"); assert_eq!(err.cx.as_deref(), Some("ContextExpr(2)")); } #[tokio::test] async fn async_unsafe_closure() { #[errify_with(|| format!("closure {arg}"))] async unsafe fn func(arg: i32) -> Result { Err(ErrorWithContext::new(arg)) } let err = unsafe { func(1).await.unwrap_err() }; assert_eq!(err.msg.deref(), "1"); assert_eq!(err.cx.as_deref(), Some("closure 1")); } #[tokio::test] async fn async_unsafe_fn() { fn context() -> impl Display { ContextExpr::new(2) } #[errify_with(context)] async unsafe fn func(arg: i32) -> Result { Err(ErrorWithContext::new(arg)) } let err = unsafe { func(1).await.unwrap_err() }; assert_eq!(err.msg.deref(), "1"); assert_eq!(err.cx.as_deref(), Some("ContextExpr(2)")); } #[test] fn method() { #[derive(Debug)] struct Struct; impl Struct { #[errify_with(|| format!("closure self = {self:?}"))] fn func(&self, arg: String) -> Result { Err(ErrorWithContext::new(arg)) } } let err = Struct.func("argument".to_owned()).unwrap_err(); assert_eq!(err.msg.deref(), "argument"); assert_eq!(err.cx.as_deref(), Some("closure self = Struct")); } #[test] fn trait_method() { trait Trait { fn func(&self, arg: String) -> Result; } #[derive(Debug)] struct Struct; impl Trait for Struct { #[errify_with(|| format!("closure self = {self:?}"))] fn func(&self, arg: String) -> Result { Err(ErrorWithContext::new(arg)) } } let err = Trait::func(&Struct, "argument".to_owned()).unwrap_err(); assert_eq!(err.msg.deref(), "argument"); assert_eq!(err.cx.as_deref(), Some("closure self = Struct")); } #[test] fn check_visibility() { pub mod multiple { use super::*; pub mod module { use super::*; #[errify_with(|| format!("closure {arg}"))] pub fn func(arg: i32) -> Result { Err(ErrorWithContext::new(arg)) } } } let err = multiple::module::func(1).unwrap_err(); assert_eq!(err.msg.deref(), "1"); assert_eq!(err.cx.as_deref(), Some("closure 1")); } #[cfg(feature = "anyhow")] #[test] fn anyhow_error() { #[errify_with(|| format!("closure {arg} = {}", arg))] fn func(arg: i32) -> Result { Err(anyhow::anyhow!("error {}", arg)) } let err = func(1).unwrap_err(); let context_err = err.to_string(); let custom_err = err.root_cause().to_string(); assert_eq!(context_err, "closure 1 = 1"); assert_eq!(custom_err, "error 1"); } #[cfg(feature = "eyre")] #[test] fn eyre_error() { #[errify_with(|| format!("closure {arg} = {}", arg))] fn func(arg: i32) -> Result { Err(eyre::eyre!("error {}", arg)) } let err = func(1).unwrap_err(); let context_err = err.to_string(); let custom_err = err.root_cause().to_string(); assert_eq!(context_err, "closure 1 = 1"); assert_eq!(custom_err, "error 1"); }