8cc1265
use std::fmt;
use ::queue::QueueError;
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(QueueError),
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,
/// 本地队列已满且等待超时。
QueueFull {
depth: usize,
capacity: usize,
},
/// 本地队列已关闭(进程正在退出)。
QueueClosed,
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::QueueFull { depth, capacity } => {
write!(f, "email queue is full: {depth}/{capacity} pending")
}
Self::QueueClosed => write!(f, "email queue is closed"),
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<QueueError> for EmailError {
fn from(err: QueueError) -> Self {
Self::Queue(err)
}
}
impl From<serde_json::Error> for EmailError {
fn from(err: serde_json::Error) -> Self {
Self::Serde(err)
}
}
impl From<SmtpError> for EmailError {
fn from(err: SmtpError) -> Self {
Self::Smtp(err)
}
}
impl From<AddressError> for EmailError {
fn from(err: AddressError) -> Self {
Self::Address(err)
}
}
impl From<LettreError> for EmailError {
fn from(err: LettreError) -> Self {
Self::Lettre(err)
}
}
impl From<base64::DecodeError> for EmailError {
fn from(err: base64::DecodeError) -> Self {
Self::Base64(err)
}
}
impl From<std::io::Error> for EmailError {
fn from(err: std::io::Error) -> Self {
Self::Io(err)
}
}