diff --git a/src/job.rs b/src/job.rs index 04163ac0c..61f9aaff7 100644 --- a/src/job.rs +++ b/src/job.rs @@ -201,9 +201,17 @@ impl Job { println!("{}", String::from_utf8_lossy(&body)); } match task::block_on(smtp.send(context, recipients_list, body, self.job_id)) { + Err(crate::smtp::send::Error::SendTimeout(err)) => { + warn!(context, "SMTP send timed out {:?}", err); + smtp.disconnect(); + self.try_again_later( + TryAgain::AtOnce, + Some("send-timeout".to_string()), + ); + } Err(crate::smtp::send::Error::SendError(err)) => { // Remote error, retry later. - info!(context, "SMTP failed to send: {}", err); + warn!(context, "SMTP failed to send: {}", err); smtp.disconnect(); self.try_again_later(TryAgain::AtOnce, Some(err.to_string())); } diff --git a/src/smtp/send.rs b/src/smtp/send.rs index c1439b965..7489e4714 100644 --- a/src/smtp/send.rs +++ b/src/smtp/send.rs @@ -1,11 +1,16 @@ //! # SMTP message sending +use std::time::Duration; + use super::Smtp; use async_smtp::*; use crate::context::Context; use crate::events::Event; +/// SMTP send times out after 15 minutes +const SEND_TIMEOUT: u64 = 15 * 60; + pub type Result = std::result::Result; #[derive(Debug, Fail)] @@ -16,6 +21,14 @@ pub enum Error { SendError(#[cause] async_smtp::smtp::error::Error), #[fail(display = "SMTP has no transport")] NoTransport, + #[fail(display = "SMTP send timed out")] + SendTimeout(#[cause] async_std::future::TimeoutError), +} + +impl From for Error { + fn from(err: async_std::future::TimeoutError) -> Error { + Error::SendTimeout(err) + } } impl Smtp { @@ -44,14 +57,17 @@ impl Smtp { message, ); if let Some(ref mut transport) = self.transport { - transport.send(mail).await.map_err(Error::SendError)?; + let res = async_std::future::timeout(Duration::from_secs(SEND_TIMEOUT), async move { + transport.send(mail).await.map_err(Error::SendError) + }) + .await?; - context.call_cb(Event::SmtpMessageSent(format!( - "Message len={} was smtp-sent to {}", - message_len, recipients_display - ))); - - Ok(()) + res.map(|_response| { + context.call_cb(Event::SmtpMessageSent(format!( + "Message len={} was smtp-sent to {}", + message_len, recipients_display + ))); + }) } else { warn!( context,