diff --git a/provider/core/src/buf/serde.rs b/provider/core/src/buf/serde.rs index 5fa989a0374..38825f0319f 100644 --- a/provider/core/src/buf/serde.rs +++ b/provider/core/src/buf/serde.rs @@ -232,6 +232,7 @@ where #[cfg(feature = "deserialize_json")] impl From for DataError { + #[track_caller] fn from(e: serde_json::error::Error) -> Self { DataErrorKind::Deserialize .with_str_context("serde_json") @@ -241,6 +242,7 @@ impl From for DataError { #[cfg(feature = "deserialize_bincode_1")] impl From for DataError { + #[track_caller] fn from(e: bincode::Error) -> Self { DataErrorKind::Deserialize .with_str_context("bincode") @@ -250,6 +252,7 @@ impl From for DataError { #[cfg(feature = "deserialize_postcard_1")] impl From for DataError { + #[track_caller] fn from(e: postcard::Error) -> Self { DataErrorKind::Deserialize .with_str_context("postcard") diff --git a/provider/core/src/error.rs b/provider/core/src/error.rs index 0903299f299..cb853f8891b 100644 --- a/provider/core/src/error.rs +++ b/provider/core/src/error.rs @@ -87,11 +87,14 @@ pub struct DataError { /// Whether this error was created in silent mode to not log. pub silent: bool, + + /// The source location where the error was created. + pub location: core::panic::Location<'static>, } impl fmt::Display for DataError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "ICU4X data error")?; + write!(f, "ICU4X data error at {}", self.location)?; if self.kind != DataErrorKind::Custom { write!(f, ": {}", self.kind)?; } @@ -110,35 +113,41 @@ impl DataErrorKind { /// /// If possible, you should attach context using a `with_` function. #[inline] + #[track_caller] pub const fn into_error(self) -> DataError { DataError { kind: self, marker: None, str_context: None, silent: false, + location: *core::panic::Location::caller(), } } /// Creates a [`DataError`] with a data marker context. #[inline] + #[track_caller] pub const fn with_marker(self, marker: DataMarkerInfo) -> DataError { self.into_error().with_marker(marker) } /// Creates a [`DataError`] with a string context. #[inline] + #[track_caller] pub const fn with_str_context(self, context: &'static str) -> DataError { self.into_error().with_str_context(context) } /// Creates a [`DataError`] with a type name context. #[inline] + #[track_caller] pub fn with_type_context(self) -> DataError { self.into_error().with_type_context::() } /// Creates a [`DataError`] with a request context. #[inline] + #[track_caller] pub fn with_req(self, marker: DataMarkerInfo, req: DataRequest) -> DataError { self.into_error().with_req(marker, req) } @@ -147,12 +156,14 @@ impl DataErrorKind { impl DataError { /// Returns a new, empty [`DataError`] with kind Custom and a string error message. #[inline] + #[track_caller] pub const fn custom(str_context: &'static str) -> Self { Self { kind: DataErrorKind::Custom, marker: None, str_context: Some(str_context), silent: false, + location: *core::panic::Location::caller(), } } @@ -164,6 +175,7 @@ impl DataError { marker: Some(marker.id), str_context: self.str_context, silent: self.silent, + location: self.location, } } @@ -175,6 +187,7 @@ impl DataError { marker: self.marker, str_context: Some(context), silent: self.silent, + location: self.location, } } @@ -241,12 +254,14 @@ impl DataError { } #[inline] + #[track_caller] pub(crate) fn for_type() -> DataError { DataError { kind: DataErrorKind::Downcast(core::any::type_name::()), marker: None, str_context: None, silent: false, + location: *core::panic::Location::caller(), } } } @@ -255,6 +270,7 @@ impl core::error::Error for DataError {} #[cfg(feature = "std")] impl From for DataError { + #[track_caller] fn from(e: std::io::Error) -> Self { log::warn!("I/O error: {e}"); DataErrorKind::Io(e.kind()).into_error()