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 ] |
52 | macro_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 ] |
109 | macro_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 ] |
150 | macro_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 | |