mirror of
https://github.com/tokio-rs/tracing.git
synced 2025-10-02 07:20:35 +00:00
core: add std::error::Error
as a new primitive type (#277)
## Motivation Currently, errors are typically recorded using their `fmt::Display` or `fmt::Debug` implementations. This doesn't give the subscriber much control over how the error is recorded --- in particular, it cannot decide whether to format the error using `Display` or `Debug`, and it cannot access the error's `source` or downcast it to another error type. The `std::error::Error` type is implemented by a majority of errors in both the standard library and in most crates, so its use is fairly widespread. ## Solution This commit adds `dyn std::error::Error + 'static` as a new primitive type. The `'static` bound is included so that the error can be downcast. Closes: #222 Signed-off-by: Eliza Weisman <eliza@buoyant.io>
This commit is contained in:
parent
59b57ae7a7
commit
f6a375e29d
@ -121,11 +121,11 @@ pub struct Iter {
|
||||
/// to be printed or stored in some other data structure.
|
||||
///
|
||||
/// The `Visit` trait provides default implementations for `record_i64`,
|
||||
/// `record_u64`, `record_bool`, and `record_str` which simply forward the
|
||||
/// recorded value to `record_debug`. Thus, `record_debug` is the only method
|
||||
/// which a `Visit` implementation *must* implement. However, visitors may
|
||||
/// override the default implementations of these functions in order to
|
||||
/// implement type-specific behavior.
|
||||
/// `record_u64`, `record_bool`, `record_str`, and `record_error`, which simply
|
||||
/// forward the recorded value to `record_debug`. Thus, `record_debug` is the
|
||||
/// only method which a `Visit` implementation *must* implement. However,
|
||||
/// visitors may override the default implementations of these functions in
|
||||
/// order to implement type-specific behavior.
|
||||
///
|
||||
/// Additionally, when a visitor receives a value of a type it does not care
|
||||
/// about, it is free to ignore those values completely. For example, a
|
||||
@ -162,6 +162,9 @@ pub struct Iter {
|
||||
/// `examples/counters.rs`, which demonstrates a very simple metrics system
|
||||
/// implemented using `tracing`.
|
||||
///
|
||||
/// **Note:** the `record_error` trait method is only available when the Rust
|
||||
/// standard library is present, as it requires the `std::error::Error` trait.
|
||||
///
|
||||
/// [`Value`]: trait.Value.html
|
||||
/// [recorded]: trait.Value.html#method.record
|
||||
/// [`Subscriber`]: ../subscriber/trait.Subscriber.html
|
||||
@ -190,6 +193,15 @@ pub trait Visit {
|
||||
self.record_debug(field, &value)
|
||||
}
|
||||
|
||||
/// Records a type implementing `Error`.
|
||||
///
|
||||
/// **Note**: this is only enabled when the Rust standard library is
|
||||
/// present.
|
||||
#[cfg(feature = "std")]
|
||||
fn record_error(&mut self, field: &Field, value: &(dyn std::error::Error + 'static)) {
|
||||
self.record_debug(field, &format_args!("{}", value))
|
||||
}
|
||||
|
||||
/// Visit a value implementing `fmt::Debug`.
|
||||
fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug);
|
||||
}
|
||||
@ -313,6 +325,16 @@ impl Value for str {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl crate::sealed::Sealed for dyn std::error::Error + 'static {}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl Value for dyn std::error::Error + 'static {
|
||||
fn record(&self, key: &Field, visitor: &mut dyn Visit) {
|
||||
visitor.record_error(key, self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized> crate::sealed::Sealed for &'a T where T: Value + crate::sealed::Sealed + 'a {}
|
||||
|
||||
impl<'a, T: ?Sized> Value for &'a T
|
||||
|
Loading…
x
Reference in New Issue
Block a user