From 6a0d024c69dc6c0a060191085f66c5dc25f1426e Mon Sep 17 00:00:00 2001
From: BlackDex <black.dex@gmail.com>
Date: Mon, 14 Sep 2020 20:47:46 +0200
Subject: [PATCH] Format some common Lettre errors a bit simpler

Currently when for example using the admin interface to send out a test e-mail just
returns `SmtpError`. This is not very helpful. What i have done.

- Match some common Lettre errors to return the error message.
- Other errors will just be passed on as before.

Some small other changes:
- Fixed a clippy warning about using clone().
- Fixed a typo where Lettere was spelled with one t.
---
 src/error.rs |  2 +-
 src/mail.rs  | 24 +++++++++++++++++++++---
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/src/error.rs b/src/error.rs
index 71ec8a61..fd5f1805 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -79,7 +79,7 @@ make_error! {
     RegexError(RegexErr): _has_source, _api_error,
     YubiError(YubiErr):   _has_source, _api_error,
 
-    LetreError(LettreErr):    _has_source, _api_error,
+    LettreError(LettreErr):   _has_source, _api_error,
     AddressError(AddrErr):    _has_source, _api_error,
     SmtpError(SmtpErr):       _has_source, _api_error,
     FromStrError(FromStrErr): _has_source, _api_error,
diff --git a/src/mail.rs b/src/mail.rs
index 0aadf3c2..bfde2529 100644
--- a/src/mail.rs
+++ b/src/mail.rs
@@ -54,7 +54,7 @@ fn mailer() -> SmtpTransport {
             for wanted_mechanism in mechanism.split(',') {
                 for m in &allowed_mechanisms {
                     if m.to_string().to_lowercase() == wanted_mechanism.trim_matches(|c| c == '"' || c == '\'' || c == ' ').to_lowercase() {
-                        selected_mechanisms.push(m.clone());
+                        selected_mechanisms.push(*m);
                     }
                 }
             };
@@ -330,6 +330,24 @@ fn send_email(address: &str, subject: &str, body_html: &str, body_text: &str) ->
         .subject(subject)
         .multipart(alternative)?;
 
-    let _ = mailer().send(&email)?;
-    Ok(())
+    match mailer().send(&email) {
+        Ok(_) => Ok(()),
+        // Match some common errors and make them more user friendly
+        Err(e) => match e {
+            lettre::transport::smtp::Error::Client(x) => {
+                err!(format!("SMTP Client error: {}", x));
+            },
+            lettre::transport::smtp::Error::Transient(x) => {
+                err!(format!("SMTP 4xx error: {:?}", x.message));
+            },
+            lettre::transport::smtp::Error::Permanent(x) => {
+                err!(format!("SMTP 5xx error: {:?}", x.message));
+            },
+            lettre::transport::smtp::Error::Io(x) => {
+                err!(format!("SMTP IO error: {}", x));
+            },
+            // Fallback for all other errors
+            _ => Err(e.into())
+        }
+    }
 }