From fd5514454f5ca20554df35e2a373a3bbfe1ffe7c Mon Sep 17 00:00:00 2001 From: Ed Page Date: Fri, 10 Jan 2025 09:27:31 -0600 Subject: [PATCH] fix: Add key tracking for all error types --- src/error.rs | 39 +++++++++++++++++++++++++++++++++++++-- tests/testsuite/errors.rs | 10 ++++++++-- tests/testsuite/log.rs | 2 +- 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/error.rs b/src/error.rs index 2d738b94..831e52b9 100644 --- a/src/error.rs +++ b/src/error.rs @@ -78,6 +78,16 @@ pub enum ConfigError { key: Option, }, + /// Custom message + At { + /// Error being extended with a path + error: Box, + + /// The key in the configuration hash of this value (if available where the + /// error is generated). + key: Option, + }, + /// Custom message Message(String), @@ -130,7 +140,15 @@ impl ConfigError { key: Some(key.into()), }, - _ => self, + Self::At { error, .. } => Self::At { + error, + key: Some(key.into()), + }, + + other => Self::At { + error: Box::new(other), + key: Some(key.into()), + }, } } @@ -157,8 +175,15 @@ impl ConfigError { expected, key: Some(concat(key)), }, + Self::At { error, key } => Self::At { + error, + key: Some(concat(key)), + }, Self::NotFound(key) => Self::NotFound(concat(Some(key))), - _ => self, + other => Self::At { + error: Box::new(other), + key: Some(concat(None)), + }, } } @@ -217,6 +242,16 @@ impl fmt::Display for ConfigError { Ok(()) } + ConfigError::At { ref error, ref key } => { + write!(f, "{error}")?; + + if let Some(ref key) = *key { + write!(f, " for key `{key}`")?; + } + + Ok(()) + } + ConfigError::FileParse { ref cause, ref uri } => { write!(f, "{cause}")?; diff --git a/tests/testsuite/errors.rs b/tests/testsuite/errors.rs index 8647044d..3a41d572 100644 --- a/tests/testsuite/errors.rs +++ b/tests/testsuite/errors.rs @@ -134,7 +134,10 @@ fn test_get_missing_field() { .unwrap(); let res = c.get::("inner"); - assert_data_eq!(res.unwrap_err().to_string(), str!["missing field `value2`"]); + assert_data_eq!( + res.unwrap_err().to_string(), + str!["missing field `value2` for key `inner`"] + ); } #[test] @@ -342,5 +345,8 @@ fn test_deserialize_missing_field() { .unwrap(); let res = c.try_deserialize::(); - assert_data_eq!(res.unwrap_err().to_string(), str!["missing field `value2`"]); + assert_data_eq!( + res.unwrap_err().to_string(), + str!["missing field `value2` for key `inner`"] + ); } diff --git a/tests/testsuite/log.rs b/tests/testsuite/log.rs index 29bf7eca..d8cda030 100644 --- a/tests/testsuite/log.rs +++ b/tests/testsuite/log.rs @@ -53,6 +53,6 @@ fn test_load_level_lowercase() { assert!(s.is_err()); assert_data_eq!( s.unwrap_err().to_string(), - str!["enum Level does not have variant constructor error"] + str!["enum Level does not have variant constructor error for key `log`"] ); }