use std::fmt; use lettre::address::AddressError; use lettre::error::Error as LettreError; use lettre::transport::smtp::Error as SmtpError; #[derive(Debug)] pub enum EmailError { Config(String), InvalidConfig(String), Disabled, Queue(redis::RedisError), Serde(serde_json::Error), Smtp(SmtpError), Address(AddressError), Lettre(LettreError), TemplateNotFound(String), TemplateRender(String), Base64(base64::DecodeError), AttachmentTooLarge { actual: usize, max: usize }, Missing(String), Io(std::io::Error), Cancelled, Other(String), } impl fmt::Display for EmailError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::Config(msg) => write!(f, "email config error: {msg}"), Self::InvalidConfig(msg) => write!(f, "email invalid config: {msg}"), Self::Disabled => write!(f, "email service is disabled"), Self::Queue(err) => write!(f, "email queue error: {err}"), Self::Serde(err) => write!(f, "email serde error: {err}"), Self::Smtp(err) => write!(f, "email smtp error: {err}"), Self::Address(err) => write!(f, "email address error: {err}"), Self::Lettre(err) => write!(f, "email lettre error: {err}"), Self::TemplateNotFound(name) => write!(f, "email template not found: {name}"), Self::TemplateRender(msg) => write!(f, "email template render error: {msg}"), Self::Base64(err) => write!(f, "email base64 decode error: {err}"), Self::AttachmentTooLarge { actual, max } => { write!(f, "attachment too large: {actual} bytes (max {max})") } Self::Missing(msg) => write!(f, "missing: {msg}"), Self::Io(err) => write!(f, "email io error: {err}"), Self::Cancelled => write!(f, "email operation cancelled"), Self::Other(msg) => write!(f, "email error: {msg}"), } } } impl std::error::Error for EmailError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { Self::Queue(err) => Some(err), Self::Serde(err) => Some(err), Self::Smtp(err) => Some(err), Self::Address(err) => Some(err), Self::Lettre(err) => Some(err), Self::Base64(err) => Some(err), Self::Io(err) => Some(err), _ => None, } } } impl From for EmailError { fn from(err: redis::RedisError) -> Self { Self::Queue(err) } } impl From for EmailError { fn from(err: serde_json::Error) -> Self { Self::Serde(err) } } impl From for EmailError { fn from(err: SmtpError) -> Self { Self::Smtp(err) } } impl From for EmailError { fn from(err: AddressError) -> Self { Self::Address(err) } } impl From for EmailError { fn from(err: LettreError) -> Self { Self::Lettre(err) } } impl From for EmailError { fn from(err: base64::DecodeError) -> Self { Self::Base64(err) } } impl From for EmailError { fn from(err: std::io::Error) -> Self { Self::Io(err) } }