You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Tracing supports recording a type implementing std::error::Error with a method Visit::record_error. Currently, one way to record such type in event or span macros is by writing something similar to
error!(error = &error as &dyn std::error::Error);
One could bring std::error::Error into scope as StdError, but even then it can be considered cumbersome to write.
Also, users might have to use different syntax depending on type of error:
some_fallible_fn().inspect_err(|error:&Error| {// notice the missing '&'error!(error = error as &dyn std::error::Error);});ifletErr(error) = some_fallible_fn(){// here '&' is requirederror!(error = &error as &dyn std::error::Error);}
I consider this too explicit. I do not see any reason why Debug and Display would have a dedicated syntax, while Error requires spelling out the type cast every time, especially considering that errors are added to traces as frequently as any other value (at least for me that's the case).
It might be valuable to gather data on whether recording errors with ... as &dyn std::error::Error is the most common way, or are there any popular alternatives.
Why not just use the ? or % for errors?
In my opinion, if Visit has a method specifically for recording errors, then that feature should be available for users in span and event macros, which are the basic blocks for defining spans and traces. For logging subscribers this is probably not that big of a difference, but for other subscribers that might collect statistics or other data, this distinction might be important.
Proposal
I propose to introduce syntax for recording errors in event and span macros in tracing and add ErrorValue to tracing-core as an analogous to tracing_core::field::DebugValue and tracing_core::field::DisplayValue.
~, aka tilde, is currently disallowed in Rust when writing ~expr to help users who might think this is a unary bitwise not operator, recommending to use ! instead, thus making error!(~err) fail before macro expansion,
!, aka exclamation mark, might clash with Rust's negation operator in error!(error = !error)
Alternatives
Don't add anything
Currently there is one other way to record an error using the record_error method - using the instrument macro.
Edit: I was wrong, there's an open PR to implement that #3057.
Thus, one alternative is to not add additional support for recording errors in event and span macros.
Function error_as_dyn or trait ErrorExt
tracing could recommend users to cast the error to &dyn StdError with a function. This option results in less jarring syntax than manually casting, but still not as concise as a single sigil or keyword.
// name up for debatefnerror_as_dyn<'a,T>(error:&'a (dyn std::error::Error + 'static),) -> &'a (dyn std::error::Error + 'static){
error
}// example usageerror!(error = error_as_dyn(&error));
It could also be possible to define trait ErrorExt with method as_dyn, but I failed at figuring out the lifetime bounds. As far as I know there's not such trait or utility function in standard library.
Wait until valuable is stabilized
Personally, I've never used the valuable feature, but from what I understand it could remove the need for a special syntax by allowing users to implement valuable::Valuable for their own error's, or implement it for all errors (if possible).
Docs
Write examples, blog posts, documentation, etc. on how to structure programs to better utilize current tracing features for logging errors. Of course, this is a good thing to do, regardless of the future of this issue.
Sidenote
I believe this a really simple feature to implement. I already have a partially working implementation (I chose ~ as the sigil, but it's invalid Rust as described above), so the only thing left is to decide if this is a correct path forward, then bikeshed the exact syntax, implement it, and lastly fill in the test suite for every event and span macro (probably the worst part).
The text was updated successfully, but these errors were encountered:
Feature Request
Crates
tracing-core
,tracing
Motivation
Tracing supports recording a type implementing
std::error::Error
with a methodVisit::record_error
. Currently, one way to record such type inevent
orspan
macros is by writing something similar toOne could bring
std::error::Error
into scope asStdError
, but even then it can be considered cumbersome to write.Also, users might have to use different syntax depending on type of
error
:I consider this too explicit. I do not see any reason why
Debug
andDisplay
would have a dedicated syntax, whileError
requires spelling out the type cast every time, especially considering that errors are added to traces as frequently as any other value (at least for me that's the case).It might be valuable to gather data on whether recording errors with
... as &dyn std::error::Error
is the most common way, or are there any popular alternatives.Why not just use the
?
or%
for errors?In my opinion, if
Visit
has a method specifically for recording errors, then that feature should be available for users inspan
andevent
macros, which are the basic blocks for defining spans and traces. For logging subscribers this is probably not that big of a difference, but for other subscribers that might collect statistics or other data, this distinction might be important.Proposal
I propose to introduce syntax for recording errors in
event
andspan
macros intracing
and addErrorValue
totracing-core
as an analogous totracing_core::field::DebugValue
andtracing_core::field::DisplayValue
.Possible syntax candidates are:
Sigil
#
, aka pound sign/hashtag/octothorpSigil
^
, aka caretSigil
@
, aka at signKeyword
There is a limited number of symbols available in rust. One alternative is to use a keyword like
err
ore
.Keyword and a sigil
Mixing is also an option, e.g.
e%
:Other, most likely invalid candidates
~
, aka tilde, is currently disallowed in Rust when writing~expr
to help users who might think this is a unary bitwise not operator, recommending to use!
instead, thus makingerror!(~err)
fail before macro expansion,!
, aka exclamation mark, might clash with Rust's negation operator inerror!(error = !error)
Alternatives
Don't add anything
Currently there is one other way to record an error using therecord_error
method - using theinstrument
macro.Edit: I was wrong, there's an open PR to implement that #3057.
Thus, one alternative is to not add additional support for recording errors in
event
andspan
macros.Function
error_as_dyn
or traitErrorExt
tracing
could recommend users to cast the error to&dyn StdError
with a function. This option results in less jarring syntax than manually casting, but still not as concise as a single sigil or keyword.It could also be possible to define trait
ErrorExt
with methodas_dyn
, but I failed at figuring out the lifetime bounds. As far as I know there's not such trait or utility function in standard library.Wait until
valuable
is stabilizedPersonally, I've never used the
valuable
feature, but from what I understand it could remove the need for a special syntax by allowing users to implementvaluable::Valuable
for their own error's, or implement it for all errors (if possible).Docs
Write examples, blog posts, documentation, etc. on how to structure programs to better utilize current tracing features for logging errors. Of course, this is a good thing to do, regardless of the future of this issue.
Sidenote
I believe this a really simple feature to implement. I already have a partially working implementation (I chose
~
as the sigil, but it's invalid Rust as described above), so the only thing left is to decide if this is a correct path forward, then bikeshed the exact syntax, implement it, and lastly fill in the test suite for every event and span macro (probably the worst part).The text was updated successfully, but these errors were encountered: