Last active
April 25, 2025 15:10
-
-
Save radix/8a673a4c36512560a1f132dbf634508e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/tracing-subscriber/src/fmt/format/json.rs b/tracing-subscriber/src/fmt/format/json.rs | |
index 3ef0fcd6..5f63d40f 100644 | |
--- a/tracing-subscriber/src/fmt/format/json.rs | |
+++ b/tracing-subscriber/src/fmt/format/json.rs | |
@@ -530,6 +530,20 @@ impl field::Visit for JsonVisitor<'_> { | |
.insert(field.name(), serde_json::Value::from(value)); | |
} | |
+ #[cfg(feature = "std")] | |
+ fn record_error(&mut self, field: &Field, value: &(dyn std::error::Error + 'static)) { | |
+ panic!("Hello? Is this even being called?"); | |
+ // TODO: Switch to https://github.com/rust-lang/rust/issues/58520 when it's stable | |
+ let mut error_chain = vec![]; | |
+ let mut current_error: Option<&(dyn std::error::Error + 'static)> = Some(value); | |
+ while let Some(err) = current_error { | |
+ error_chain.push(serde_json::Value::from(format!("{:?}", err))); | |
+ current_error = err.source(); | |
+ } | |
+ let sources = serde_json::Value::Array(error_chain); | |
+ self.values.insert(field.name(), sources); | |
+ } | |
+ | |
fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { | |
match field.name() { | |
// Skip fields that are actually log metadata that have already been handled | |
@@ -827,6 +841,41 @@ mod test { | |
}); | |
} | |
+ /// The chain of error sources is included in the result. | |
+ #[test] | |
+ fn error_chain() { | |
+ let expected = "{}"; | |
+ let subscriber = subscriber() | |
+ .flatten_event(false) | |
+ .with_current_span(true) | |
+ .with_span_list(true); | |
+ #[derive(Debug)] | |
+ struct Error { | |
+ source: core::num::ParseIntError, | |
+ } | |
+ impl core::error::Error for Error { | |
+ fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { | |
+ Some(&self.source) | |
+ } | |
+ } | |
+ impl core::fmt::Display for Error { | |
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | |
+ write!(f, "Hello World")?; | |
+ Ok(()) | |
+ } | |
+ } | |
+ | |
+ let result: Result<u32, core::num::ParseIntError> = "abc".parse(); | |
+ let err = Error { | |
+ source: result.unwrap_err(), | |
+ }; | |
+ test_json(expected, subscriber, || { | |
+ tracing::error!( | |
+ error = &err as &(dyn std::error::Error + 'static), | |
+ "error json test" | |
+ ); | |
+ }); | |
+ } | |
+ | |
fn parse_as_json(buffer: &MockMakeWriter) -> serde_json::Value { | |
let buf = String::from_utf8(buffer.buf().to_vec()).unwrap(); | |
let json = buf |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment