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