1/// Return early with an error.
2///
3/// This macro is equivalent to `return Err(From::from($err))`.
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(From::from($err)); }`.
67///
68/// Analogously to `assert!`, `ensure!` takes a condition and exits the function
69/// if the condition fails. Unlike `assert!`, `ensure!` returns an `Error`
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, $msg:literal $(,)?) => {
111 if !$cond {
112 return $crate::private::Err($crate::eyre!($msg));
113 }
114 };
115 ($cond:expr, $err:expr $(,)?) => {
116 if !$cond {
117 return $crate::private::Err($crate::eyre!($err));
118 }
119 };
120 ($cond:expr, $fmt:expr, $($arg:tt)*) => {
121 if !$cond {
122 return $crate::private::Err($crate::eyre!($fmt, $($arg)*));
123 }
124 };
125}
126
127/// Construct an ad-hoc error from a string.
128///
129/// This evaluates to an `Error`. It can take either just a string, or a format
130/// string with arguments. It also can take any custom type which implements
131/// `Debug` and `Display`.
132///
133/// # Example
134///
135/// ```
136/// # type V = ();
137/// #
138/// use eyre::{eyre, Result};
139///
140/// fn lookup(key: &str) -> Result<V> {
141/// if key.len() != 16 {
142/// return Err(eyre!("key length must be 16 characters, got {:?}", key));
143/// }
144///
145/// // ...
146/// # Ok(())
147/// }
148/// ```
149#[macro_export]
150macro_rules! eyre {
151 ($msg:literal $(,)?) => ({
152 let error = $crate::private::format_err($crate::private::format_args!($msg));
153 error
154 });
155 ($err:expr $(,)?) => ({
156 use $crate::private::kind::*;
157 let error = match $err {
158 error => (&error).eyre_kind().new(error),
159 };
160 error
161 });
162 ($fmt:expr, $($arg:tt)*) => {
163 $crate::private::new_adhoc($crate::private::format!($fmt, $($arg)*))
164 };
165}
166