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