diff --git a/tracing-core/src/field.rs b/tracing-core/src/field.rs index c46b00317..2abe13d1d 100644 --- a/tracing-core/src/field.rs +++ b/tracing-core/src/field.rs @@ -44,6 +44,9 @@ use core::{ ops::Range, }; +#[cfg(feature = "std")] +use std::error; + use self::private::ValidLen; /// An opaque key allowing _O_(1) access to a field in a `Span`'s key-value @@ -270,6 +273,12 @@ pub struct DisplayValue(T); #[derive(Clone)] pub struct DebugValue(T); +/// A 'Value' which serializes error and it's sources. +#[cfg(feature = "std")] +#[derive(Clone, Debug)] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +pub struct ErrorValue<'a, T: error::Error + 'static>(&'a T); + /// Wraps a type implementing `fmt::Display` as a `Value` that can be /// recorded using its `Display` implementation. pub fn display(t: T) -> DisplayValue @@ -288,6 +297,17 @@ where DebugValue(t) } +/// Wraps a reference to a type implementing `error::Error` as a `Value` +/// that records the error's message and sources. +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +pub fn error<'a, T>(t: &'a T) -> ErrorValue<'a, T> +where + T: error::Error + 'static, +{ + ErrorValue(t) +} + struct HexBytes<'a>(&'a [u8]); impl<'a> fmt::Debug for HexBytes<'a> { @@ -658,6 +678,20 @@ impl fmt::Debug for DebugValue { } } +// ===== impl ErrorValue ===== +#[cfg(feature = "std")] +impl crate::sealed::Sealed for ErrorValue<'_, T> {} + +#[cfg(feature = "std")] +impl<'a, T> Value for ErrorValue<'a, T> +where + T: error::Error + 'static, +{ + fn record(&self, key: &Field, visitor: &mut dyn Visit) { + visitor.record_error(key, self.0) + } +} + impl crate::sealed::Sealed for Empty {} impl Value for Empty { #[inline]