melib/error.rs: switch summary<->details identifiers

They are more intuitive like this.
This commit is contained in:
Manos Pitsidianakis 2022-09-02 12:12:12 +03:00
parent aa99b0d787
commit eb5949dc9b
6 changed files with 73 additions and 46 deletions

View File

@ -222,8 +222,8 @@ impl Backends {
#[derive(Debug, Clone)]
pub enum BackendEvent {
Notice {
description: Option<String>,
content: String,
description: String,
content: Option<String>,
level: crate::LoggingLevel,
},
Refresh(RefreshEvent),
@ -233,8 +233,8 @@ pub enum BackendEvent {
impl From<MeliError> for BackendEvent {
fn from(val: MeliError) -> BackendEvent {
BackendEvent::Notice {
description: val.summary.as_ref().map(|s| s.to_string()),
content: val.to_string(),
description: val.summary.to_string(),
content: Some(val.to_string()),
level: crate::LoggingLevel::ERROR,
}
}

View File

@ -746,8 +746,8 @@ impl ImapConnection {
(self.uid_store.event_consumer)(
self.uid_store.account_hash,
crate::backends::BackendEvent::Notice {
description: None,
content: response_code.to_string(),
description: response_code.to_string(),
content: None,
level: crate::logging::LoggingLevel::ERROR,
},
);
@ -763,8 +763,8 @@ impl ImapConnection {
(self.uid_store.event_consumer)(
self.uid_store.account_hash,
crate::backends::BackendEvent::Notice {
description: None,
content: response_code.to_string(),
description: response_code.to_string(),
content: None,
level: crate::logging::LoggingLevel::ERROR,
},
);

View File

@ -85,14 +85,18 @@ impl ErrorKind {
#[derive(Debug, Clone)]
pub struct MeliError {
pub summary: Option<Cow<'static, str>>,
pub details: Cow<'static, str>,
pub summary: Cow<'static, str>,
pub details: Option<Cow<'static, str>>,
pub source: Option<std::sync::Arc<dyn Error + Send + Sync + 'static>>,
pub kind: ErrorKind,
}
pub trait IntoMeliError {
fn set_err_summary<M>(self, msg: M) -> MeliError
where
M: Into<Cow<'static, str>>;
fn set_err_details<M>(self, msg: M) -> MeliError
where
M: Into<Cow<'static, str>>;
fn set_err_kind(self, kind: ErrorKind) -> MeliError;
@ -117,6 +121,15 @@ impl<I: Into<MeliError>> IntoMeliError for I {
err.set_summary(msg)
}
#[inline]
fn set_err_details<M>(self, msg: M) -> MeliError
where
M: Into<Cow<'static, str>>,
{
let err: MeliError = self.into();
err.set_details(msg)
}
#[inline]
fn set_err_kind(self, kind: ErrorKind) -> MeliError {
let err: MeliError = self.into();
@ -146,21 +159,33 @@ impl MeliError {
M: Into<Cow<'static, str>>,
{
MeliError {
summary: None,
details: msg.into(),
summary: msg.into(),
details: None,
source: None,
kind: ErrorKind::None,
}
}
pub fn set_details<M>(mut self, details: M) -> MeliError
where
M: Into<Cow<'static, str>>,
{
if let Some(old_details) = self.details.as_ref() {
self.details = Some(format!("{}. {}", old_details, details.into()).into());
} else {
self.details = Some(details.into());
}
self
}
pub fn set_summary<M>(mut self, summary: M) -> MeliError
where
M: Into<Cow<'static, str>>,
{
if let Some(old_summary) = self.summary.take() {
self.summary = Some(format!("{}. {}", old_summary, summary.into()).into());
if self.summary.is_empty() {
self.summary = summary.into();
} else {
self.summary = Some(summary.into());
self.summary = format!("{}. {}", self.summary, summary.into()).into();
}
self
}
@ -181,10 +206,10 @@ impl MeliError {
impl fmt::Display for MeliError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(summary) = self.summary.as_ref() {
writeln!(f, "Summary: {}", summary)?;
writeln!(f, "Summary: {}", self.summary)?;
if let Some(details) = self.details.as_ref() {
write!(f, "{}", details)?;
}
write!(f, "{}", self.details)?;
if let Some(source) = self.source.as_ref() {
write!(f, "\nCaused by: {}", source)?;
}
@ -205,7 +230,7 @@ impl From<io::Error> for MeliError {
#[inline]
fn from(kind: io::Error) -> MeliError {
MeliError::new(kind.to_string())
.set_summary(format!("{:?}", kind.kind()))
.set_details(kind.kind().to_string())
.set_source(Some(Arc::new(kind)))
.set_kind(ErrorKind::OSError)
}
@ -214,21 +239,21 @@ impl From<io::Error> for MeliError {
impl<'a> From<Cow<'a, str>> for MeliError {
#[inline]
fn from(kind: Cow<'_, str>) -> MeliError {
MeliError::new(format!("{:?}", kind))
MeliError::new(kind.to_string())
}
}
impl From<string::FromUtf8Error> for MeliError {
#[inline]
fn from(kind: string::FromUtf8Error) -> MeliError {
MeliError::new(format!("{:?}", kind)).set_source(Some(Arc::new(kind)))
MeliError::new(kind.to_string()).set_source(Some(Arc::new(kind)))
}
}
impl From<str::Utf8Error> for MeliError {
#[inline]
fn from(kind: str::Utf8Error) -> MeliError {
MeliError::new(format!("{:?}", kind)).set_source(Some(Arc::new(kind)))
MeliError::new(kind.to_string()).set_source(Some(Arc::new(kind)))
}
}
//use std::option;
@ -242,7 +267,7 @@ impl From<str::Utf8Error> for MeliError {
impl<T> From<std::sync::PoisonError<T>> for MeliError {
#[inline]
fn from(kind: std::sync::PoisonError<T>) -> MeliError {
MeliError::new(format!("{}", kind))
MeliError::new(kind.to_string()).set_kind(ErrorKind::Bug)
}
}
@ -252,7 +277,9 @@ impl<T: Sync + Send + 'static + core::fmt::Debug> From<native_tls::HandshakeErro
{
#[inline]
fn from(kind: native_tls::HandshakeError<T>) -> MeliError {
MeliError::new(format!("{}", kind)).set_source(Some(Arc::new(kind)))
MeliError::new(kind.to_string())
.set_source(Some(Arc::new(kind)))
.set_kind(ErrorKind::Network)
}
}
@ -260,14 +287,16 @@ impl<T: Sync + Send + 'static + core::fmt::Debug> From<native_tls::HandshakeErro
impl From<native_tls::Error> for MeliError {
#[inline]
fn from(kind: native_tls::Error) -> MeliError {
MeliError::new(format!("{}", kind)).set_source(Some(Arc::new(kind)))
MeliError::new(kind.to_string())
.set_source(Some(Arc::new(kind)))
.set_kind(ErrorKind::Network)
}
}
impl From<std::num::ParseIntError> for MeliError {
#[inline]
fn from(kind: std::num::ParseIntError) -> MeliError {
MeliError::new(format!("{}", kind)).set_source(Some(Arc::new(kind)))
MeliError::new(kind.to_string()).set_source(Some(Arc::new(kind)))
}
}
@ -283,35 +312,35 @@ impl From<isahc::Error> for MeliError {
impl From<serde_json::error::Error> for MeliError {
#[inline]
fn from(kind: serde_json::error::Error) -> MeliError {
MeliError::new(format!("{}", kind)).set_source(Some(Arc::new(kind)))
MeliError::new(kind.to_string()).set_source(Some(Arc::new(kind)))
}
}
impl From<Box<dyn Error + Sync + Send + 'static>> for MeliError {
#[inline]
fn from(kind: Box<dyn Error + Sync + Send + 'static>) -> MeliError {
MeliError::new(format!("{}", kind)).set_source(Some(kind.into()))
MeliError::new(kind.to_string()).set_source(Some(kind.into()))
}
}
impl From<std::ffi::NulError> for MeliError {
#[inline]
fn from(kind: std::ffi::NulError) -> MeliError {
MeliError::new(format!("{}", kind)).set_source(Some(Arc::new(kind)))
MeliError::new(kind.to_string()).set_source(Some(Arc::new(kind)))
}
}
impl From<Box<bincode::ErrorKind>> for MeliError {
#[inline]
fn from(kind: Box<bincode::ErrorKind>) -> MeliError {
MeliError::new(format!("{}", kind)).set_source(Some(Arc::new(kind)))
MeliError::new(kind.to_string()).set_source(Some(Arc::new(kind)))
}
}
impl From<nix::Error> for MeliError {
#[inline]
fn from(kind: nix::Error) -> MeliError {
MeliError::new(format!("{}", kind)).set_source(Some(Arc::new(kind)))
MeliError::new(kind.to_string()).set_source(Some(Arc::new(kind)))
}
}
@ -319,14 +348,14 @@ impl From<nix::Error> for MeliError {
impl From<rusqlite::Error> for MeliError {
#[inline]
fn from(kind: rusqlite::Error) -> MeliError {
MeliError::new(format!("{}", kind)).set_source(Some(Arc::new(kind)))
MeliError::new(kind.to_string()).set_source(Some(Arc::new(kind)))
}
}
impl From<libloading::Error> for MeliError {
#[inline]
fn from(kind: libloading::Error) -> MeliError {
MeliError::new(format!("{}", kind)).set_source(Some(Arc::new(kind)))
MeliError::new(kind.to_string()).set_source(Some(Arc::new(kind)))
}
}
@ -347,16 +376,14 @@ impl From<String> for MeliError {
impl From<nom::Err<(&[u8], nom::error::ErrorKind)>> for MeliError {
#[inline]
fn from(kind: nom::Err<(&[u8], nom::error::ErrorKind)>) -> MeliError {
MeliError::new("Parsing error")
.set_source(Some(Arc::new(MeliError::new(format!("{}", kind)))))
MeliError::new("Parsing error").set_source(Some(Arc::new(MeliError::new(kind.to_string()))))
}
}
impl From<nom::Err<(&str, nom::error::ErrorKind)>> for MeliError {
#[inline]
fn from(kind: nom::Err<(&str, nom::error::ErrorKind)>) -> MeliError {
MeliError::new("Parsing error")
.set_source(Some(Arc::new(MeliError::new(format!("{}", kind)))))
MeliError::new("Parsing error").set_details(kind.to_string())
}
}

View File

@ -2229,8 +2229,8 @@ pub fn save_draft(
..
}) => {
context.replies.push_back(UIEvent::Notification(
summary.map(|s| s.into()),
details.into(),
details.map(|s| s.into()),
summary.to_string(),
Some(NotificationType::Error(kind)),
));
}

View File

@ -1239,20 +1239,20 @@ send_mail = '/bin/false'
let mut new_file = ConfigFile::new(TEST_CONFIG).unwrap();
let err = FileSettings::validate(new_file.path.clone(), false, true).unwrap_err();
assert!(err.details.as_ref().starts_with("You must set a global `composing` option. If you override `composing` in each account, you can use a dummy global like follows"));
assert!(err.summary.as_ref().starts_with("You must set a global `composing` option. If you override `composing` in each account, you can use a dummy global like follows"));
new_file
.file
.write_all("[composing]\nsend_mail = '/bin/false'\n".as_bytes())
.unwrap();
let err = FileSettings::validate(new_file.path.clone(), false, true).unwrap_err();
assert_eq!(err.details.as_ref(), "Configuration error (account-name): root_path `/path/to/root/mailbox` is not a valid directory.");
assert_eq!(err.summary.as_ref(), "Configuration error (account-name): root_path `/path/to/root/mailbox` is not a valid directory.");
/* Test unrecognised configuration entries error */
let new_file = ConfigFile::new(EXTRA_CONFIG).unwrap();
let err = FileSettings::validate(new_file.path.clone(), false, true).unwrap_err();
assert_eq!(
err.details.as_ref(),
err.summary.as_ref(),
"Unrecognised configuration values: {\"index_style\": \"Compact\"}"
);

View File

@ -1004,14 +1004,14 @@ impl State {
format!(
"{}: {}{}{}",
self.context.accounts[&account_hash].name(),
description.as_ref().map(|s| s.as_str()).unwrap_or(""),
if description.is_some() { ": " } else { "" },
content.as_str()
description.as_str(),
if content.is_some() { ": " } else { "" },
content.as_ref().map(|s| s.as_str()).unwrap_or("")
),
level,
);
self.rcv_event(UIEvent::StatusEvent(StatusEvent::DisplayMessage(
content.to_string(),
description.to_string(),
)));
return;
}