So I've finally had enough of typing
.map_err(|error| {
tracing::warn!("uncooperative yak!", %error);
error
})?;
and decided to do something about it. I currently have the following (nightly only), but would really like ideas and challenges on the overall API at an early stage:
.or_warn("uncooperative yak!")?;
this relies on
- a trait extension to
Result - a custom type which stores a tracing event alongside the Ok(value) or Err(err) variants of a result
- emitting the event on
?
In particular I'd like opinions on:
- the extension methods naming:
or_warn()/or_debug()etc emit onErrand_...()emit onOk- should there be something that always emits? currently
.and_info().or_warn()?only emits one of the two possible events.
- ability to chain:
- supporting
.and_info().or_warn()?;reads logically - is it worth the extra work and complexity to avoid allowing
.or_warn().and_info()?which would be confusing?
- supporting
- ability to add fields
- currently the methods require a single
name: &'static str - any extra fields need to be included in a wrapping
Spanfirst - this keeps the method call chain simple and provides a clear intent "I'm going to do some stuff and any warnings should include this info about it"
- the alternative would be to accept a struct of fields with an empty Default, but that feels ugly to me
- currently the methods require a single
- because of the way
tracingusesstatics to allow for self-referential structs, it's not possible to create aDefaultCallsitewith the location of the?as the module-path & line number.[1]- How much of a killer would it be to have
origin_module_pathandorigin_lineas fields on the event, while.metadata().module_path()&.metadata().line()return the location insidetracing_result? - I may be able to construct a custom type to work around this, but it's a lot of extra complexity and my gut says that
tracingwent the macros + static route for multiple reasons, not just performance.
- How much of a killer would it be to have
Thanks in advance!
The location is available at runtime, but runtime values can't be used to construct
MetaData. To have this done at compile time would mean switching to a macro-based approach which isn't the API I want. ↩︎