mirror of
https://github.com/eyre-rs/eyre.git
synced 2025-09-28 21:41:58 +00:00
Automatically convert to external errors w/ ensure! and bail! (#95)
* Automatically convert to external errors A pattern documented by thiserror is ``` pub enum MyError { ... #[error(transparent)] Other(#[from] anyhow::Error), // source and Display delegate to anyhow::Error } ``` It'd be nice for this to work with ensure! but right now, that macro returns an eyre error. With this PR, the macro additionally runs an .into(). In the case that the return type is an eyre error, obviously .into() will do nothing and be compiled away. In the case that there is a from method, the wrapping will occur. This enables eyre to be used for ergonomic 'implementation detail error' in a thiserror using system which has contractual errors. Since this conversion adds more flexibility to the result of these macros, this could break code which relies on the narrowness to inform type inference. If this is the case, update your code to specify the result type you would like to use. * Fix single-argument ensure test and allow dead code. By adding the possibility for polymorphism from an eyre error, the previous commit breaks a previous eyre test for single-argument ensure!(). This change fixes that test and adds `allow(dead_code)` to the struct used for the test for automatically converting to external errors. --------- Co-authored-by: nori li <50680474+thenorili@users.noreply.github.com>
This commit is contained in:
parent
0979ad7718
commit
a795c97a2b
@ -51,13 +51,13 @@
|
||||
#[macro_export]
|
||||
macro_rules! bail {
|
||||
($msg:literal $(,)?) => {
|
||||
return $crate::private::Err($crate::eyre!($msg));
|
||||
return $crate::private::Err($crate::eyre!($msg).into());
|
||||
};
|
||||
($err:expr $(,)?) => {
|
||||
return $crate::private::Err($crate::eyre!($err));
|
||||
return $crate::private::Err($crate::eyre!($err).into());
|
||||
};
|
||||
($fmt:expr, $($arg:tt)*) => {
|
||||
return $crate::private::Err($crate::eyre!($fmt, $($arg)*));
|
||||
return $crate::private::Err($crate::eyre!($fmt, $($arg)*).into());
|
||||
};
|
||||
}
|
||||
|
||||
@ -114,17 +114,17 @@ macro_rules! ensure {
|
||||
};
|
||||
($cond:expr, $msg:literal $(,)?) => {
|
||||
if !$cond {
|
||||
return $crate::private::Err($crate::eyre!($msg));
|
||||
return $crate::private::Err($crate::eyre!($msg).into());
|
||||
}
|
||||
};
|
||||
($cond:expr, $err:expr $(,)?) => {
|
||||
if !$cond {
|
||||
return $crate::private::Err($crate::eyre!($err));
|
||||
return $crate::private::Err($crate::eyre!($err).into());
|
||||
}
|
||||
};
|
||||
($cond:expr, $fmt:expr, $($arg:tt)*) => {
|
||||
if !$cond {
|
||||
return $crate::private::Err($crate::eyre!($fmt, $($arg)*));
|
||||
return $crate::private::Err($crate::eyre!($fmt, $($arg)*).into());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -40,7 +40,8 @@ fn test_ensure() {
|
||||
};
|
||||
assert!(f().is_err());
|
||||
|
||||
let f = || {
|
||||
// Tests single-argument `ensure!`
|
||||
let f = || -> Result<()> {
|
||||
ensure!(v + v == 1);
|
||||
Ok(())
|
||||
};
|
||||
@ -48,6 +49,24 @@ fn test_ensure() {
|
||||
f().unwrap_err().to_string(),
|
||||
"Condition failed: `v + v == 1`",
|
||||
);
|
||||
|
||||
// Tests automatically converting to external errors with ensure!()
|
||||
let f = || -> Result<(), SomeWrappingErr> {
|
||||
ensure!(false, "this will fail");
|
||||
Ok(())
|
||||
};
|
||||
assert!(f().is_err());
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct SomeWrappingErr {
|
||||
err: eyre::Error,
|
||||
}
|
||||
|
||||
impl From<eyre::Error> for SomeWrappingErr {
|
||||
fn from(err: eyre::Error) -> Self {
|
||||
SomeWrappingErr { err }
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
Loading…
x
Reference in New Issue
Block a user