#[report]
Expand description
Adapts a function to provide user-friendly error output for main
functions and tests.
use snafu::prelude::*;
#[snafu::report]
fn main() -> Result<()> {
let _v = frobnicate_the_mumbletypeg()?;
Ok(())
}
fn frobnicate_the_mumbletypeg() -> Result<u8> {
api::contact_frobnicate_api().context(FrobnicateSnafu)
}
#[derive(Debug, Snafu)]
#[snafu(display("Unable to frobnicate the mumbletypeg"))]
struct FrobnicateError {
source: api::ContactFrobnicateApiError,
}
type Result<T, E = FrobnicateError> = std::result::Result<T, E>;
mod api {
use crate::config;
use snafu::prelude::*;
pub fn contact_frobnicate_api() -> Result<u8> {
config::load_password().context(ContactFrobnicateApiSnafu)
}
#[derive(Debug, Snafu)]
#[snafu(display("Could not contact the mumbletypeg API"))]
pub struct ContactFrobnicateApiError {
source: crate::config::MissingPasswordError,
}
pub type Result<T, E = ContactFrobnicateApiError> = std::result::Result<T, E>;
}
mod config {
use snafu::prelude::*;
pub fn load_password() -> Result<u8> {
MissingPasswordSnafu.fail()
}
#[derive(Debug, Snafu)]
#[snafu(display("The configuration has no password"))]
pub struct MissingPasswordError {
backtrace: snafu::Backtrace,
}
pub type Result<T, E = MissingPasswordError> = std::result::Result<T, E>;
}
When using #[snafu::report]
, the output of running this program
may look like (backtrace edited for clarity and brevity):
Error: Unable to frobnicate the mumbletypeg
Caused by these errors (recent errors listed first):
1: Could not contact the mumbletypeg API
2: The configuration has no password
Backtrace:
[... output edited ...]
3: <std::backtrace::Backtrace as snafu::GenerateImplicitData>::generate
at crates/snafu/src/lib.rs:1210:9
4: backtrace_example::config::MissingPasswordSnafu::build
at ./src/main.rs:48:21
5: backtrace_example::config::MissingPasswordSnafu::fail
at ./src/main.rs:48:21
6: backtrace_example::config::load_password
at ./src/main.rs:45:9
7: backtrace_example::api::contact_frobnicate_api
at ./src/main.rs:29:9
8: backtrace_example::frobnicate_the_mumbletypeg
at ./src/main.rs:13:5
9: backtrace_example::main::{{closure}}
at ./src/main.rs:7:14
10: backtrace_example::main
at ./src/main.rs:5:1
[... output edited ...]
Contrast this to the default output produced when returning a
Result
:
Error: FrobnicateError { source: ContactFrobnicateApiError { source: MissingPasswordError { backtrace: Backtrace [...2000+ bytes of backtrace...] } } }
This macro is syntax sugar for using Report
; please read
its documentation for detailed information, especially if you wish to
see backtraces in the output.
§Usage with other procedural macros
This macro should work with other common procedural macros. It has been tested with
tokio::main
tokio::test
async_std::main
async_std::test
Depending on the implementation details of each procedural macro, you
may need to experiment by placing snafu::report
before or after
other macro invocations.