eyre/macros.rs
1/// Return early with an error.
2///
3/// This macro is equivalent to `return Err(eyre!(<args>))`.
4///
5/// # Example
6///
7/// ```
8/// # use eyre::{bail, Result};
9/// #
10/// # fn has_permission(user: usize, resource: usize) -> bool {
11/// # true
12/// # }
13/// #
14/// # fn main() -> Result<()> {
15/// # let user = 0;
16/// # let resource = 0;
17/// #
18/// if !has_permission(user, resource) {
19/// bail!("permission denied for accessing {}", resource);
20/// }
21/// # Ok(())
22/// # }
23/// ```
24///
25/// ```
26/// # use eyre::{bail, Result};
27/// # use thiserror::Error;
28/// #
29/// # const MAX_DEPTH: usize = 1;
30/// #
31/// #[derive(Error, Debug)]
32/// enum ScienceError {
33/// #[error("recursion limit exceeded")]
34/// RecursionLimitExceeded,
35/// # #[error("...")]
36/// # More = (stringify! {
37/// ...
38/// # }, 1).1,
39/// }
40///
41/// # fn main() -> Result<()> {
42/// # let depth = 0;
43/// # let err: &'static dyn std::error::Error = &ScienceError::RecursionLimitExceeded;
44/// #
45/// if depth > MAX_DEPTH {
46/// bail!(ScienceError::RecursionLimitExceeded);
47/// }
48/// # Ok(())
49/// # }
50/// ```
51#[macro_export]
52macro_rules! bail {
53 ($msg:literal $(,)?) => {
54 return $crate::private::Err($crate::eyre!($msg))
55 };
56 ($err:expr $(,)?) => {
57 return $crate::private::Err($crate::eyre!($err))
58 };
59 ($fmt:expr, $($arg:tt)*) => {
60 return $crate::private::Err($crate::eyre!($fmt, $($arg)*))
61 };
62}
63
64/// Return early with an error if a condition is not satisfied.
65///
66/// This macro is equivalent to `if !$cond { return Err(eyre!(<other args>)); }`.
67///
68/// Analogously to `assert!`, `ensure!` takes a condition and exits the function
69/// if the condition fails. Unlike `assert!`, `ensure!` returns an `eyre::Result`
70/// rather than panicking.
71///
72/// # Example
73///
74/// ```
75/// # use eyre::{ensure, Result};
76/// #
77/// # fn main() -> Result<()> {
78/// # let user = 0;
79/// #
80/// ensure!(user == 0, "only user 0 is allowed");
81/// # Ok(())
82/// # }
83/// ```
84///
85/// ```
86/// # use eyre::{ensure, Result};
87/// # use thiserror::Error;
88/// #
89/// # const MAX_DEPTH: usize = 1;
90/// #
91/// #[derive(Error, Debug)]
92/// enum ScienceError {
93/// #[error("recursion limit exceeded")]
94/// RecursionLimitExceeded,
95/// # #[error("...")]
96/// # More = (stringify! {
97/// ...
98/// # }, 1).1,
99/// }
100///
101/// # fn main() -> Result<()> {
102/// # let depth = 0;
103/// #
104/// ensure!(depth <= MAX_DEPTH, ScienceError::RecursionLimitExceeded);
105/// # Ok(())
106/// # }
107/// ```
108#[macro_export]
109macro_rules! ensure {
110 ($cond:expr $(,)?) => {
111 $crate::ensure!($cond, concat!("Condition failed: `", stringify!($cond), "`"))
112 };
113 ($cond:expr, $msg:literal $(,)?) => {
114 if !$cond {
115 return $crate::private::Err($crate::eyre!($msg));
116 }
117 };
118 ($cond:expr, $err:expr $(,)?) => {
119 if !$cond {
120 return $crate::private::Err($crate::eyre!($err));
121 }
122 };
123 ($cond:expr, $fmt:expr, $($arg:tt)*) => {
124 if !$cond {
125 return $crate::private::Err($crate::eyre!($fmt, $($arg)*));
126 }
127 };
128}
129
130/// Construct an ad-hoc error from a string.
131///
132/// This evaluates to a `Report`. It can take either just a string, or a format
133/// string with arguments. It also can take any custom type which implements
134/// `Debug` and `Display`.
135///
136/// # Example
137///
138/// ```
139/// # type V = ();
140/// #
141/// use eyre::{eyre, Result};
142///
143/// fn lookup(key: &str) -> Result<V> {
144/// if key.len() != 16 {
145/// return Err(eyre!("key length must be 16 characters, got {:?}", key));
146/// }
147///
148/// // ...
149/// # Ok(())
150/// }
151/// ```
152#[macro_export]
153macro_rules! eyre {
154 ($msg:literal $(,)?) => ({
155 let error = $crate::private::format_err($crate::private::format_args!($msg));
156 error
157 });
158 ($err:expr $(,)?) => ({
159 use $crate::private::kind::*;
160 let error = match $err {
161 error => (&error).eyre_kind().new(error),
162 };
163 error
164 });
165 ($fmt:expr, $($arg:tt)*) => {
166 $crate::private::new_adhoc($crate::private::format!($fmt, $($arg)*))
167 };
168}