mirror of
https://github.com/chatmail/core.git
synced 2026-05-22 16:26:31 +03:00
Resultify Smtp::send
This commit is contained in:
committed by
Floris Bruynooghe
parent
20ce5f6967
commit
14287b12ae
16
src/job.rs
16
src/job.rs
@@ -20,6 +20,7 @@ use crate::message::MsgId;
|
|||||||
use crate::message::{self, Message, MessageState};
|
use crate::message::{self, Message, MessageState};
|
||||||
use crate::mimefactory::{vec_contains_lowercase, Loaded, MimeFactory};
|
use crate::mimefactory::{vec_contains_lowercase, Loaded, MimeFactory};
|
||||||
use crate::param::*;
|
use crate::param::*;
|
||||||
|
use crate::smtp::SmtpError;
|
||||||
use crate::sql;
|
use crate::sql;
|
||||||
|
|
||||||
// results in ~3 weeks for the last backoff timespan
|
// results in ~3 weeks for the last backoff timespan
|
||||||
@@ -184,11 +185,22 @@ impl Job {
|
|||||||
// otherwise might send it twice.
|
// otherwise might send it twice.
|
||||||
let mut smtp = context.smtp.lock().unwrap();
|
let mut smtp = context.smtp.lock().unwrap();
|
||||||
match smtp.send(context, recipients_list, body, self.job_id) {
|
match smtp.send(context, recipients_list, body, self.job_id) {
|
||||||
Err(err) => {
|
Err(SmtpError::SendError(err)) => {
|
||||||
|
// Remote error, retry later.
|
||||||
smtp.disconnect();
|
smtp.disconnect();
|
||||||
warn!(context, "smtp failed: {}", err);
|
info!(context, "SMTP failed to send: {}", err);
|
||||||
self.try_again_later(TryAgain::AtOnce, Some(err.to_string()));
|
self.try_again_later(TryAgain::AtOnce, Some(err.to_string()));
|
||||||
}
|
}
|
||||||
|
Err(SmtpError::EnvelopeError(err)) => {
|
||||||
|
// Local error, job is invalid, do not retry.
|
||||||
|
smtp.disconnect();
|
||||||
|
warn!(context, "SMTP job is invalid: {}", err);
|
||||||
|
}
|
||||||
|
Err(SmtpError::NoTransport) => {
|
||||||
|
// Should never happen.
|
||||||
|
// It does not even make sense to disconnect here.
|
||||||
|
error!(context, "SMTP job failed because SMTP has no transport");
|
||||||
|
}
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
// smtp success, update db ASAP, then delete smtp file
|
// smtp success, update db ASAP, then delete smtp file
|
||||||
if 0 != self.foreign_id {
|
if 0 != self.foreign_id {
|
||||||
|
|||||||
31
src/smtp.rs
31
src/smtp.rs
@@ -1,6 +1,8 @@
|
|||||||
use lettre::smtp::client::net::*;
|
use lettre::smtp::client::net::*;
|
||||||
use lettre::*;
|
use lettre::*;
|
||||||
|
|
||||||
|
use failure::Fail;
|
||||||
|
|
||||||
use crate::constants::*;
|
use crate::constants::*;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
@@ -17,6 +19,16 @@ pub struct Smtp {
|
|||||||
from: Option<EmailAddress>,
|
from: Option<EmailAddress>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Fail)]
|
||||||
|
pub enum SmtpError {
|
||||||
|
#[fail(display = "Envelope error: {}", _0)]
|
||||||
|
EnvelopeError(lettre::error::Error),
|
||||||
|
#[fail(display = "Send error: {}", _0)]
|
||||||
|
SendError(lettre::smtp::error::Error),
|
||||||
|
#[fail(display = "SMTP has no transport")]
|
||||||
|
NoTransport,
|
||||||
|
}
|
||||||
|
|
||||||
impl Smtp {
|
impl Smtp {
|
||||||
/// Create a new Smtp instances.
|
/// Create a new Smtp instances.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
@@ -144,7 +156,7 @@ impl Smtp {
|
|||||||
recipients: Vec<EmailAddress>,
|
recipients: Vec<EmailAddress>,
|
||||||
message: Vec<u8>,
|
message: Vec<u8>,
|
||||||
job_id: u32,
|
job_id: u32,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), SmtpError> {
|
||||||
let message_len = message.len();
|
let message_len = message.len();
|
||||||
|
|
||||||
let recipients_display = recipients
|
let recipients_display = recipients
|
||||||
@@ -155,10 +167,8 @@ impl Smtp {
|
|||||||
|
|
||||||
if let Some(ref mut transport) = self.transport {
|
if let Some(ref mut transport) = self.transport {
|
||||||
let envelope = match Envelope::new(self.from.clone(), recipients) {
|
let envelope = match Envelope::new(self.from.clone(), recipients) {
|
||||||
Ok(env) => env,
|
Ok(envelope) => envelope,
|
||||||
Err(err) => {
|
Err(e) => return Err(SmtpError::EnvelopeError(e)),
|
||||||
bail!("{}", err);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
let mail = SendableEmail::new(
|
let mail = SendableEmail::new(
|
||||||
envelope,
|
envelope,
|
||||||
@@ -175,15 +185,14 @@ impl Smtp {
|
|||||||
self.transport_connected = true;
|
self.transport_connected = true;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => return Err(SmtpError::SendError(err)),
|
||||||
bail!("SMTP failed len={}: error: {}", message_len, err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bail!(
|
warn!(
|
||||||
"uh? SMTP has no transport, failed to send to {:?}",
|
context,
|
||||||
recipients_display
|
"uh? SMTP has no transport, failed to send to {}", recipients_display
|
||||||
);
|
);
|
||||||
|
return Err(SmtpError::NoTransport);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user