From b3db164b9294b7a085553dd70ceeedcebfcd733d Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 24 May 2018 15:14:13 -0700 Subject: [PATCH] Use `failure::Error` for ConfigError instead of a String. --- src/cargo/util/config.rs | 41 +++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/cargo/util/config.rs b/src/cargo/util/config.rs index d62ebc159..a9ff2eeae 100644 --- a/src/cargo/util/config.rs +++ b/src/cargo/util/config.rs @@ -847,21 +847,21 @@ impl fmt::Display for ConfigKey { /// Internal error for serde errors. #[derive(Debug)] pub struct ConfigError { - message: String, + error: failure::Error, definition: Option, } impl ConfigError { fn new(message: String, definition: Definition) -> ConfigError { ConfigError { - message, + error: failure::err_msg(message), definition: Some(definition), } } fn expected(key: &str, expected: &str, found: &ConfigValue) -> ConfigError { ConfigError { - message: format!( + error: format_err!( "`{}` expected {}, but found a {}", key, expected, @@ -873,31 +873,42 @@ impl ConfigError { fn missing(key: String) -> ConfigError { ConfigError { - message: format!("missing config key `{}`", key), + error: format_err!("missing config key `{}`", key), definition: None, } } fn with_key_context(self, key: String, definition: Definition) -> ConfigError { ConfigError { - message: format!("could not load config key `{}`: {}", key, self), + error: format_err!("could not load config key `{}`: {}", key, self), definition: Some(definition), } } } impl std::error::Error for ConfigError { + // This can be removed once 1.27 is stable. fn description(&self) -> &str { - self.message.as_str() + "An error has occurred." } } +// Future Note: Currently we cannot override Fail::cause (due to +// specialization) so we have no way to return the underlying causes. In the +// future, once this limitation is lifted, this should instead implement +// `cause` and avoid doing the cause formatting here. impl fmt::Display for ConfigError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let message = self + .error + .causes() + .map(|e| e.to_string()) + .collect::>() + .join("\nCaused by:\n "); if let Some(ref definition) = self.definition { - write!(f, "error in {}: {}", definition, self.message) + write!(f, "error in {}: {}", definition, message) } else { - self.message.fmt(f) + message.fmt(f) } } } @@ -905,24 +916,16 @@ impl fmt::Display for ConfigError { impl de::Error for ConfigError { fn custom(msg: T) -> Self { ConfigError { - message: msg.to_string(), + error: failure::err_msg(msg.to_string()), definition: None, } } } -// TODO: AFAIK, you cannot override Fail::cause (due to specialization), so we -// have no way to bubble up the underlying error. For now, it just formats -// the underlying cause as a string. impl From for ConfigError { - fn from(e: failure::Error) -> Self { - let message = e - .causes() - .map(|e| e.to_string()) - .collect::>() - .join("\nCaused by:\n "); + fn from(error: failure::Error) -> Self { ConfigError { - message, + error, definition: None, } } -- 2.30.2