anyhow

Macro anyhow 

Source
macro_rules! anyhow {
    ($val:expr) => { ... };
    (($($format:tt)+), extend: $($ext:expr),+) => { ... };
    ($val:expr, extend: $($ext:expr),+) => { ... };
    ($($tok:tt)+) => { ... };
}
Expand description

Create a new ErrorContext stack

if only one expression is passed in, the value is passed directly to ErrorContext::new

let error = anyhow!("this is a literal value");
assert_eq!(format!("{error}"), "this is a literal value");

otherwise, the arguments to this macro are passed through to format!, which generates the error message

let error = anyhow!("this is a format string, x = {}", 1234);
assert_eq!(format!("{error}"), "this is a format string, x = 1234");

if you want to use this behaviour while inlining all variables into the format string, append a trailing comma, like this:

let x = 1234;
let bad  = anyhow!("this variable reference wont work cuz no comma: x = {x}");
assert_eq!(format!("{bad}"), "this variable reference wont work cuz no comma: x = {x}");

let good = anyhow!("format string with inlined variable references, x = {x}",);
assert_eq!(format!("{good}"), "format string with inlined variable references, x = 1234")

if a single expression is passed in, followed by , extend:, the value is passed directly to ErrorContext::new and all further expressions are inserted into the error as extensions:

#[derive(Clone, Copy)]
struct A;
impl Extension for A {}

let error = anyhow!("literal message", extend: Arc::new(A));
assert_eq!(format!("{error}"), "literal message");
assert!(error.find_extension::<A>().is_some());

to insert extensions while using format! for the error message, the format string and the format parameters must be wrapped in parentheses:

#[derive(Clone, Copy)]
struct A;
impl Extension for A {}

let error = anyhow!(("format string, x = {}", 1234), extend: Arc::new(A));
assert_eq!(format!("{error}"), "format string, x = 1234");
assert!(error.find_extension::<A>().is_some());

this is also how you use format strings with all variables inlined, no trailing comma needed this time:

#[derive(Clone, Copy)]
struct A;
impl Extension for A {}

let x = 1234;
let error = anyhow!(("format string, x = {x}"), extend: Arc::new(A));
assert_eq!(format!("{error}"), "format string, x = 1234");
assert!(error.find_extension::<A>().is_some());