-
Notifications
You must be signed in to change notification settings - Fork 754
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
attributes: add err(Debug)
meta to use Debug
impl
#1631
Changes from 4 commits
b8d94fe
83e030a
0bfac9f
5768a50
db5a161
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -182,7 +182,7 @@ use syn::{ | |||||||||||||||||||||||||||||||||||||||
/// ``` | ||||||||||||||||||||||||||||||||||||||||
/// | ||||||||||||||||||||||||||||||||||||||||
/// If the function returns a `Result<T, E>` and `E` implements `std::fmt::Display`, you can add | ||||||||||||||||||||||||||||||||||||||||
/// `err` to emit error events when the function returns `Err`: | ||||||||||||||||||||||||||||||||||||||||
/// `err` or `err(Display)` to emit error events when the function returns `Err`: | ||||||||||||||||||||||||||||||||||||||||
/// | ||||||||||||||||||||||||||||||||||||||||
/// ``` | ||||||||||||||||||||||||||||||||||||||||
/// # use tracing_attributes::instrument; | ||||||||||||||||||||||||||||||||||||||||
|
@@ -191,6 +191,18 @@ use syn::{ | |||||||||||||||||||||||||||||||||||||||
/// Ok(()) | ||||||||||||||||||||||||||||||||||||||||
/// } | ||||||||||||||||||||||||||||||||||||||||
/// ``` | ||||||||||||||||||||||||||||||||||||||||
/// | ||||||||||||||||||||||||||||||||||||||||
/// The above example will be emitting error events using the `std::fmt::Display` implementation. | ||||||||||||||||||||||||||||||||||||||||
/// If `E` implements `std::fmt::Debug`, you can also make it use that implementation with | ||||||||||||||||||||||||||||||||||||||||
/// `err(Debug)`: | ||||||||||||||||||||||||||||||||||||||||
/// | ||||||||||||||||||||||||||||||||||||||||
/// ``` | ||||||||||||||||||||||||||||||||||||||||
/// # use tracing_attributes::instrument; | ||||||||||||||||||||||||||||||||||||||||
/// #[instrument(err(Debug))] | ||||||||||||||||||||||||||||||||||||||||
/// fn my_function(arg: usize) -> Result<(), std::io::Error> { | ||||||||||||||||||||||||||||||||||||||||
/// Ok(()) | ||||||||||||||||||||||||||||||||||||||||
/// } | ||||||||||||||||||||||||||||||||||||||||
/// ``` | ||||||||||||||||||||||||||||||||||||||||
/// | ||||||||||||||||||||||||||||||||||||||||
/// `async fn`s may also be instrumented: | ||||||||||||||||||||||||||||||||||||||||
/// | ||||||||||||||||||||||||||||||||||||||||
|
@@ -393,7 +405,6 @@ fn gen_block( | |||||||||||||||||||||||||||||||||||||||
instrumented_function_name: &str, | ||||||||||||||||||||||||||||||||||||||||
self_type: Option<&syn::TypePath>, | ||||||||||||||||||||||||||||||||||||||||
) -> proc_macro2::TokenStream { | ||||||||||||||||||||||||||||||||||||||||
let err = args.err; | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
// generate the span's name | ||||||||||||||||||||||||||||||||||||||||
let span_name = args | ||||||||||||||||||||||||||||||||||||||||
|
@@ -507,29 +518,34 @@ fn gen_block( | |||||||||||||||||||||||||||||||||||||||
)) | ||||||||||||||||||||||||||||||||||||||||
})(); | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
let err_event = match args.err_mode { | ||||||||||||||||||||||||||||||||||||||||
Some(ErrorMode::Display) => Some(quote!(tracing::error!(error = %e))), | ||||||||||||||||||||||||||||||||||||||||
Some(ErrorMode::Debug) => Some(quote!(tracing::error!(error = ?e))), | ||||||||||||||||||||||||||||||||||||||||
_ => None, | ||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
// Generate the instrumented function body. | ||||||||||||||||||||||||||||||||||||||||
// If the function is an `async fn`, this will wrap it in an async block, | ||||||||||||||||||||||||||||||||||||||||
// which is `instrument`ed using `tracing-futures`. Otherwise, this will | ||||||||||||||||||||||||||||||||||||||||
// enter the span and then perform the rest of the body. | ||||||||||||||||||||||||||||||||||||||||
// If `err` is in args, instrument any resulting `Err`s. | ||||||||||||||||||||||||||||||||||||||||
if async_context { | ||||||||||||||||||||||||||||||||||||||||
let mk_fut = if err { | ||||||||||||||||||||||||||||||||||||||||
quote_spanned!(block.span()=> | ||||||||||||||||||||||||||||||||||||||||
let mk_fut = match err_event { | ||||||||||||||||||||||||||||||||||||||||
Some(err_event) => quote_spanned!(block.span()=> | ||||||||||||||||||||||||||||||||||||||||
async move { | ||||||||||||||||||||||||||||||||||||||||
match async move { #block }.await { | ||||||||||||||||||||||||||||||||||||||||
#[allow(clippy::unit_arg)] | ||||||||||||||||||||||||||||||||||||||||
Ok(x) => Ok(x), | ||||||||||||||||||||||||||||||||||||||||
Err(e) => { | ||||||||||||||||||||||||||||||||||||||||
tracing::error!(error = %e); | ||||||||||||||||||||||||||||||||||||||||
#err_event; | ||||||||||||||||||||||||||||||||||||||||
Err(e) | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||||||
quote_spanned!(block.span()=> | ||||||||||||||||||||||||||||||||||||||||
), | ||||||||||||||||||||||||||||||||||||||||
None => quote_spanned!(block.span()=> | ||||||||||||||||||||||||||||||||||||||||
async move { #block } | ||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||
), | ||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
return quote!( | ||||||||||||||||||||||||||||||||||||||||
|
@@ -566,15 +582,15 @@ fn gen_block( | |||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
if err { | ||||||||||||||||||||||||||||||||||||||||
if let Some(err_event) = err_event { | ||||||||||||||||||||||||||||||||||||||||
return quote_spanned!(block.span()=> | ||||||||||||||||||||||||||||||||||||||||
#span | ||||||||||||||||||||||||||||||||||||||||
#[allow(clippy::redundant_closure_call)] | ||||||||||||||||||||||||||||||||||||||||
match (move || #block)() { | ||||||||||||||||||||||||||||||||||||||||
#[allow(clippy::unit_arg)] | ||||||||||||||||||||||||||||||||||||||||
Ok(x) => Ok(x), | ||||||||||||||||||||||||||||||||||||||||
Err(e) => { | ||||||||||||||||||||||||||||||||||||||||
tracing::error!(error = %e); | ||||||||||||||||||||||||||||||||||||||||
#err_event; | ||||||||||||||||||||||||||||||||||||||||
Err(e) | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
|
@@ -603,7 +619,7 @@ struct InstrumentArgs { | |||||||||||||||||||||||||||||||||||||||
target: Option<LitStr>, | ||||||||||||||||||||||||||||||||||||||||
skips: HashSet<Ident>, | ||||||||||||||||||||||||||||||||||||||||
fields: Option<Fields>, | ||||||||||||||||||||||||||||||||||||||||
err: bool, | ||||||||||||||||||||||||||||||||||||||||
err_mode: Option<ErrorMode>, | ||||||||||||||||||||||||||||||||||||||||
/// Errors describing any unrecognized parse inputs that we skipped. | ||||||||||||||||||||||||||||||||||||||||
parse_warnings: Vec<syn::Error>, | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
|
@@ -728,8 +744,8 @@ impl Parse for InstrumentArgs { | |||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
args.fields = Some(input.parse()?); | ||||||||||||||||||||||||||||||||||||||||
} else if lookahead.peek(kw::err) { | ||||||||||||||||||||||||||||||||||||||||
let _ = input.parse::<kw::err>()?; | ||||||||||||||||||||||||||||||||||||||||
args.err = true; | ||||||||||||||||||||||||||||||||||||||||
let ErrorModes(mode) = input.parse()?; | ||||||||||||||||||||||||||||||||||||||||
args.err_mode = Some(mode); | ||||||||||||||||||||||||||||||||||||||||
} else if lookahead.peek(Token![,]) { | ||||||||||||||||||||||||||||||||||||||||
let _ = input.parse::<Token![,]>()?; | ||||||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||||||
|
@@ -787,6 +803,51 @@ impl Parse for Skips { | |||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
#[derive(Debug, Hash, PartialEq, Eq)] | ||||||||||||||||||||||||||||||||||||||||
enum ErrorMode { | ||||||||||||||||||||||||||||||||||||||||
Display, | ||||||||||||||||||||||||||||||||||||||||
Debug, | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
impl Default for ErrorMode { | ||||||||||||||||||||||||||||||||||||||||
fn default() -> Self { | ||||||||||||||||||||||||||||||||||||||||
ErrorMode::Display | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
impl Parse for ErrorMode { | ||||||||||||||||||||||||||||||||||||||||
fn parse(input: ParseStream<'_>) -> syn::Result<Self> { | ||||||||||||||||||||||||||||||||||||||||
if !input.peek(syn::token::Paren) { | ||||||||||||||||||||||||||||||||||||||||
return Ok(ErrorMode::default()); | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
let content; | ||||||||||||||||||||||||||||||||||||||||
let _ = syn::parenthesized!(content in input); | ||||||||||||||||||||||||||||||||||||||||
let maybe_mode: Option<Ident> = content.parse()?; | ||||||||||||||||||||||||||||||||||||||||
maybe_mode.map_or( | ||||||||||||||||||||||||||||||||||||||||
Ok(ErrorMode::default()), | ||||||||||||||||||||||||||||||||||||||||
|ident| match ident.to_string().as_str() { | ||||||||||||||||||||||||||||||||||||||||
"Debug" => Ok(ErrorMode::Debug), | ||||||||||||||||||||||||||||||||||||||||
"Display" => Ok(ErrorMode::Display), | ||||||||||||||||||||||||||||||||||||||||
_ => Err(syn::Error::new( | ||||||||||||||||||||||||||||||||||||||||
ident.span(), | ||||||||||||||||||||||||||||||||||||||||
"unknown error mode, must be Debug or Display", | ||||||||||||||||||||||||||||||||||||||||
)), | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
struct ErrorModes(ErrorMode); | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
impl Parse for ErrorModes { | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
fn parse(input: ParseStream<'_>) -> syn::Result<Self> { | ||||||||||||||||||||||||||||||||||||||||
let _ = input.parse::<kw::err>(); | ||||||||||||||||||||||||||||||||||||||||
let mode = ErrorMode::parse(input)?; | ||||||||||||||||||||||||||||||||||||||||
Ok(Self(mode)) | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like the name
Suggested change
or, we could probably just get rid of this entirely, and move the IMO, having a separate type for this is not really necessary any longer, but it's up to you... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's right, I completely missed this. I think removing |
||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
#[derive(Debug)] | ||||||||||||||||||||||||||||||||||||||||
struct Fields(Punctuated<Field, Token![,]>); | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about changing this to something like: