Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Report for user-friendly error output [todo]
[todo] rewrite feature flag docs [todo] chain rust feature flag to lower version
- Loading branch information
1 parent
d18ab69
commit 7b0f53c
Showing
10 changed files
with
506 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
use quote::quote; | ||
use syn::{spanned::Spanned, Item}; | ||
|
||
pub fn body( | ||
_attr: proc_macro::TokenStream, | ||
item: proc_macro::TokenStream, | ||
) -> syn::Result<proc_macro2::TokenStream> { | ||
let item = syn::parse::<Item>(item)?; | ||
|
||
match item { | ||
Item::Fn(f) => { | ||
let syn::ItemFn { | ||
attrs, | ||
vis, | ||
sig, | ||
block, | ||
} = f; | ||
|
||
let syn::Signature { | ||
constness, | ||
asyncness, | ||
unsafety, | ||
abi, | ||
fn_token, | ||
ident, | ||
generics, | ||
paren_token: _, | ||
inputs, | ||
variadic, | ||
output, | ||
} = sig; | ||
|
||
let output = match output { | ||
syn::ReturnType::Default => quote! {}, | ||
syn::ReturnType::Type(_, ty) => { | ||
if cfg!(feature = "rust_1_61") { | ||
quote! { | ||
-> ::snafu::Report<<#ty as ::snafu::__InternalExtractErrorType>::Err> | ||
} | ||
} else { | ||
quote! { | ||
-> ::core::result::Result<(), snafu::Report<<#ty as ::snafu::__InternalExtractErrorType>::Err>> | ||
} | ||
} | ||
} | ||
}; | ||
|
||
Ok(quote! { | ||
#(#attrs)* | ||
#vis | ||
#constness | ||
#asyncness | ||
#unsafety | ||
#abi | ||
#fn_token | ||
#ident | ||
#generics | ||
(#inputs #variadic) | ||
#output | ||
{ | ||
snafu::Report::capture(|| #block) | ||
} | ||
}) | ||
} | ||
_ => Err(syn::Error::new( | ||
item.span(), | ||
"`#[snafu::report]` may only be used on functions", | ||
)), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
Adapts a function to provide user-friendly error output for `main` | ||
functions and tests. | ||
|
||
```rust,no_run | ||
use snafu::prelude::*; | ||
#[snafu::report] | ||
fn main() -> Result<(), ApplicationError> { | ||
let _v = may_fail_with_application_error()?; | ||
Ok(()) | ||
} | ||
#[derive(Debug, Snafu)] | ||
#[snafu(display("Unable to frobnicate the mumbletypeg"))] | ||
struct ApplicationError { | ||
source: SpecificError | ||
} | ||
#[derive(Debug, Snafu)] | ||
#[snafu(display("The mumbletypeg could not be found"))] | ||
struct SpecificError { | ||
backtrace: snafu::Backtrace, | ||
} | ||
fn may_fail_with_application_error() -> Result<u8, ApplicationError> { | ||
may_fail_with_specific_error().context(ApplicationSnafu) | ||
} | ||
fn may_fail_with_specific_error() -> Result<u8, SpecificError> { | ||
SpecificSnafu.fail() | ||
} | ||
``` | ||
|
||
When using `#[snafu::report]`, the output of running this program | ||
may look like (backtrace edited for clarity and brevity): | ||
|
||
```text | ||
Unable to frobnicate the mumbletypeg | ||
Caused by: | ||
0: The mumbletypeg could not be found | ||
Backtrace: | ||
4 <snafu::backtrace_shim::Backtrace as snafu::GenerateImplicitData>::generate::h57208e368a5db816 | ||
/snafu/src/backtrace_shim.rs:15 | ||
example::SpecificSnafu::build::hff0254e61866cabb | ||
example.rs:18 | ||
5 example::SpecificSnafu::fail::hec8a0999ec6ee527 | ||
example.rs:18 | ||
6 example::may_fail_with_specific_error::h271b4f6daa5d46aa | ||
example.rs:29 | ||
7 example::may_fail_with_application_error::h20cbd2f6aead9af3 | ||
example.rs:25 | ||
8 example::main::{{closure}}::hc62fd2b706cb40f3 | ||
example.rs:7 | ||
9 snafu::report::Report<E>::capture::h81d9883cf934c7bb | ||
/snafu/src/report.rs:132 | ||
10 example::main::hf53e4b9f8a221d64 | ||
example.rs:5 | ||
``` | ||
|
||
Contrast this to the default output produced when returning a | ||
`Result`: | ||
|
||
```text | ||
Error: ApplicationError { source: DetailedError { backtrace: Backtrace(...same backtrace as above...) } } | ||
``` | ||
|
||
This macro is syntax sugar for using [`snafu::Report`][]; please read | ||
its documentation for detailed information, especially if you wish to | ||
[see backtraces][] in the output. | ||
|
||
[`snafu::Report`]: crate::Report | ||
[see backtraces]: crate::Report#interaction-with-the-provider-api |
Oops, something went wrong.