From 3ea1ce5454a705db999b8a48ae1d2d7f8ff7999a Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Sat, 9 May 2020 14:29:32 +0300 Subject: [PATCH] errors: add `source` field to MeliError --- melib/src/error.rs | 51 +++++++++++++++++++++++++--------- src/components/mail/compose.rs | 5 ++-- src/conf/accounts.rs | 2 +- 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/melib/src/error.rs b/melib/src/error.rs index 984d25d2..32e50b4a 100644 --- a/melib/src/error.rs +++ b/melib/src/error.rs @@ -30,15 +30,17 @@ use std::io; use std::result; use std::str; use std::string; +use std::sync::Arc; use nom; pub type Result = result::Result; -#[derive(Debug, Clone, Deserialize, Serialize)] +#[derive(Debug, Clone)] pub struct MeliError { pub summary: Option>, pub details: Cow<'static, str>, + pub source: Option>, } impl MeliError { @@ -49,6 +51,7 @@ impl MeliError { MeliError { summary: None, details: msg.into(), + source: None, } } @@ -59,11 +62,26 @@ impl MeliError { self.summary = Some(summary.into()); self } + + pub fn set_source( + mut self, + new_val: Option>, + ) -> MeliError { + self.source = new_val; + self + } } impl fmt::Display for MeliError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.details) + if let Some(summary) = self.summary.as_ref() { + write!(f, "Summary: {}\n", summary)?; + } + let ret = write!(f, "{}", self.details)?; + if let Some(source) = self.source.as_ref() { + write!(f, "\nCaused by: {}", source)?; + } + Ok(ret) } } @@ -74,15 +92,15 @@ impl Into for MeliError { } impl Error for MeliError { - fn description(&self) -> &str { - &self.details + fn source(&self) -> Option<&(dyn Error + 'static)> { + self.source.as_ref().map(|s| &(*(*s)) as _) } } impl From for MeliError { #[inline] fn from(kind: io::Error) -> MeliError { - MeliError::new(kind.description().to_string()) + MeliError::new(kind.to_string()).set_source(Some(Arc::new(kind))) } } @@ -103,14 +121,14 @@ impl<'a> From> for MeliError { impl From for MeliError { #[inline] fn from(kind: string::FromUtf8Error) -> MeliError { - MeliError::new(format!("{:?}", kind)) + MeliError::new(format!("{:?}", kind)).set_source(Some(Arc::new(kind))) } } impl From for MeliError { #[inline] fn from(kind: str::Utf8Error) -> MeliError { - MeliError::new(format!("{:?}", kind)) + MeliError::new(format!("{:?}", kind)).set_source(Some(Arc::new(kind))) } } //use std::option; @@ -132,7 +150,7 @@ impl From> for MeliError { impl From> for MeliError { #[inline] fn from(kind: native_tls::HandshakeError) -> MeliError { - MeliError::new(format!("{}", kind)) + MeliError::new(format!("{}", kind)).set_source(Some(Arc::new(kind))) } } @@ -140,14 +158,14 @@ impl From> for MeliError { impl From for MeliError { #[inline] fn from(kind: native_tls::Error) -> MeliError { - MeliError::new(format!("{}", kind)) + MeliError::new(format!("{}", kind)).set_source(Some(Arc::new(kind))) } } impl From for MeliError { #[inline] fn from(kind: std::num::ParseIntError) -> MeliError { - MeliError::new(format!("{}", kind)) + MeliError::new(format!("{}", kind)).set_source(Some(Arc::new(kind))) } } @@ -155,7 +173,7 @@ impl From for MeliError { impl From for MeliError { #[inline] fn from(kind: reqwest::Error) -> MeliError { - MeliError::new(format!("{}", kind)) + MeliError::new(format!("{}", kind)).set_source(Some(Arc::new(kind))) } } @@ -163,14 +181,21 @@ impl From for MeliError { impl From for MeliError { #[inline] fn from(kind: serde_json::error::Error) -> MeliError { - MeliError::new(format!("{}", kind)) + MeliError::new(format!("{}", kind)).set_source(Some(Arc::new(kind))) + } +} + +impl From> for MeliError { + #[inline] + fn from(kind: Box) -> MeliError { + MeliError::new(format!("{}", kind)).set_source(Some(kind.into())) } } impl From for MeliError { #[inline] fn from(kind: std::ffi::NulError) -> MeliError { - MeliError::new(format!("{}", kind)) + MeliError::new(format!("{}", kind)).set_source(Some(Arc::new(kind))) } } diff --git a/src/components/mail/compose.rs b/src/components/mail/compose.rs index d6eeff46..8c48b238 100644 --- a/src/components/mail/compose.rs +++ b/src/components/mail/compose.rs @@ -1333,8 +1333,9 @@ pub fn save_draft( flags: Flag, account_cursor: usize, ) { - if let Err(MeliError { summary, details }) = - context.accounts[account_cursor].save_special(bytes, mailbox_type, flags) + if let Err(MeliError { + summary, details, .. + }) = context.accounts[account_cursor].save_special(bytes, mailbox_type, flags) { context.replies.push_back(UIEvent::Notification( summary.map(|s| s.into()), diff --git a/src/conf/accounts.rs b/src/conf/accounts.rs index 9475af5d..305ea1e3 100644 --- a/src/conf/accounts.rs +++ b/src/conf/accounts.rs @@ -51,7 +51,7 @@ use std::sync::{Arc, RwLock}; pub type Worker = Option>>>; -#[derive(Serialize, Debug)] +#[derive(Debug)] pub enum MailboxStatus { Available, Failed(MeliError),