anyhow/macros.rs
1/// Return early with an error.
2///
3/// This macro is equivalent to `return Err(`[`anyhow!($args...)`][anyhow!]`)`.
4///
5/// The surrounding function's or closure's return value is required to be
6/// `Result<_,`[`anyhow::Error`][crate::Error]`>`.
7///
8/// [anyhow!]: crate::anyhow
9///
10/// # Example
11///
12/// ```
13/// # use anyhow::{bail, Result};
14/// #
15/// # fn has_permission(user: usize, resource: usize) -> bool {
16/// # true
17/// # }
18/// #
19/// # fn main() -> Result<()> {
20/// # let user = 0;
21/// # let resource = 0;
22/// #
23/// if !has_permission(user, resource) {
24/// bail!("permission denied for accessing {}", resource);
25/// }
26/// # Ok(())
27/// # }
28/// ```
29///
30/// ```
31/// # use anyhow::{bail, Result};
32/// # use thiserror::Error;
33/// #
34/// # const MAX_DEPTH: usize = 1;
35/// #
36/// #[derive(Error, Debug)]
37/// enum ScienceError {
38/// #[error("recursion limit exceeded")]
39/// RecursionLimitExceeded,
40/// # #[error("...")]
41/// # More = (stringify! {
42/// ...
43/// # }, 1).1,
44/// }
45///
46/// # fn main() -> Result<()> {
47/// # let depth = 0;
48/// #
49/// if depth > MAX_DEPTH {
50/// bail!(ScienceError::RecursionLimitExceeded);
51/// }
52/// # Ok(())
53/// # }
54/// ```
55#[macro_export]
56macro_rules! bail {
57 ($msg:literal $(,)?) => {
58 return $crate::__private::Err($crate::__anyhow!($msg))
59 };
60 ($err:expr $(,)?) => {
61 return $crate::__private::Err($crate::__anyhow!($err))
62 };
63 ($fmt:expr, $($arg:tt)*) => {
64 return $crate::__private::Err($crate::__anyhow!($fmt, $($arg)*))
65 };
66}
67
68macro_rules! __ensure {
69 ($ensure:item) => {
70 /// Return early with an error if a condition is not satisfied.
71 ///
72 /// This macro is equivalent to `if !$cond { return
73 /// Err(`[`anyhow!($args...)`][anyhow!]`); }`.
74 ///
75 /// The surrounding function's or closure's return value is required to be
76 /// `Result<_,`[`anyhow::Error`][crate::Error]`>`.
77 ///
78 /// Analogously to `assert!`, `ensure!` takes a condition and exits the function
79 /// if the condition fails. Unlike `assert!`, `ensure!` returns an `Error`
80 /// rather than panicking.
81 ///
82 /// [anyhow!]: crate::anyhow
83 ///
84 /// # Example
85 ///
86 /// ```
87 /// # use anyhow::{ensure, Result};
88 /// #
89 /// # fn main() -> Result<()> {
90 /// # let user = 0;
91 /// #
92 /// ensure!(user == 0, "only user 0 is allowed");
93 /// # Ok(())
94 /// # }
95 /// ```
96 ///
97 /// ```
98 /// # use anyhow::{ensure, Result};
99 /// # use thiserror::Error;
100 /// #
101 /// # const MAX_DEPTH: usize = 1;
102 /// #
103 /// #[derive(Error, Debug)]
104 /// enum ScienceError {
105 /// #[error("recursion limit exceeded")]
106 /// RecursionLimitExceeded,
107 /// # #[error("...")]
108 /// # More = (stringify! {
109 /// ...
110 /// # }, 1).1,
111 /// }
112 ///
113 /// # fn main() -> Result<()> {
114 /// # let depth = 0;
115 /// #
116 /// ensure!(depth <= MAX_DEPTH, ScienceError::RecursionLimitExceeded);
117 /// # Ok(())
118 /// # }
119 /// ```
120 $ensure
121 };
122}
123
124#[cfg(doc)]
125__ensure![
126 #[macro_export]
127 macro_rules! ensure {
128 ($cond:expr $(,)?) => {
129 if !$cond {
130 return $crate::__private::Err($crate::Error::msg(
131 $crate::__private::concat!("Condition failed: `", $crate::__private::stringify!($cond), "`")
132 ));
133 }
134 };
135 ($cond:expr, $msg:literal $(,)?) => {
136 if !$cond {
137 return $crate::__private::Err($crate::__anyhow!($msg));
138 }
139 };
140 ($cond:expr, $err:expr $(,)?) => {
141 if !$cond {
142 return $crate::__private::Err($crate::__anyhow!($err));
143 }
144 };
145 ($cond:expr, $fmt:expr, $($arg:tt)*) => {
146 if !$cond {
147 return $crate::__private::Err($crate::__anyhow!($fmt, $($arg)*));
148 }
149 };
150 }
151];
152
153#[cfg(not(doc))]
154__ensure![
155 #[macro_export]
156 macro_rules! ensure {
157 ($($tt:tt)*) => {
158 $crate::__parse_ensure!(
159 /* state */ 0
160 /* stack */ ()
161 /* bail */ ($($tt)*)
162 /* fuel */ (~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~)
163 /* parse */ {()}
164 /* dup */ ($($tt)*)
165 /* rest */ $($tt)*
166 )
167 };
168 }
169];
170
171/// Construct an ad-hoc error from a string or existing non-`anyhow` error
172/// value.
173///
174/// This evaluates to an [`Error`][crate::Error]. It can take either just a
175/// string, or a format string with arguments. It also can take any custom type
176/// which implements `Debug` and `Display`.
177///
178/// If called with a single argument whose type implements `std::error::Error`
179/// (in addition to `Debug` and `Display`, which are always required), then that
180/// Error impl's `source` is preserved as the `source` of the resulting
181/// `anyhow::Error`.
182///
183/// # Example
184///
185/// ```
186/// # type V = ();
187/// #
188/// use anyhow::{anyhow, Result};
189///
190/// fn lookup(key: &str) -> Result<V> {
191/// if key.len() != 16 {
192/// return Err(anyhow!("key length must be 16 characters, got {:?}", key));
193/// }
194///
195/// // ...
196/// # Ok(())
197/// }
198/// ```
199#[macro_export]
200macro_rules! anyhow {
201 ($msg:literal $(,)?) => {
202 $crate::__private::must_use({
203 let error = $crate::__private::format_err($crate::__private::format_args!($msg));
204 error
205 })
206 };
207 ($err:expr $(,)?) => {
208 $crate::__private::must_use({
209 use $crate::__private::kind::*;
210 let error = match $err {
211 error => (&error).anyhow_kind().new(error),
212 };
213 error
214 })
215 };
216 ($fmt:expr, $($arg:tt)*) => {
217 $crate::Error::msg($crate::__private::format!($fmt, $($arg)*))
218 };
219}
220
221// Not public API. This is used in the implementation of some of the other
222// macros, in which the must_use call is not needed because the value is known
223// to be used.
224#[doc(hidden)]
225#[macro_export]
226macro_rules! __anyhow {
227 ($msg:literal $(,)?) => ({
228 let error = $crate::__private::format_err($crate::__private::format_args!($msg));
229 error
230 });
231 ($err:expr $(,)?) => ({
232 use $crate::__private::kind::*;
233 let error = match $err {
234 error => (&error).anyhow_kind().new(error),
235 };
236 error
237 });
238 ($fmt:expr, $($arg:tt)*) => {
239 $crate::Error::msg($crate::__private::format!($fmt, $($arg)*))
240 };
241}