Repository: Mailu/Mailu

Issue:
fetchmail crashes due to exception
```
Traceback (most recent call last):
  File "/fetchmail.py", line 93, in <module>
    run(os.environ.get("DEBUG", None) == "True")
  File "/fetchmail.py", line 47, in run
    fetches = requests.get("http://admin/internal/fetch").json()
  File "/usr/lib/python3.7/site-packages/requests/models.py", line 897, in json
    return complexjson.loads(self.text, **kwargs)
  File "/usr/lib/python3.7/json/__init__.py", line 348, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.7/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.7/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
```


Discussion:
I'll fix it by myself.
Feel free to assign this to me.

Resolving patch:
diff --git a/optional/fetchmail/fetchmail.py b/optional/fetchmail/fetchmail.py
--- a/optional/fetchmail/fetchmail.py
+++ b/optional/fetchmail/fetchmail.py
@@ -8,6 +8,7 @@
 import re
 import requests
 import sys
+import traceback
 
 
 FETCHMAIL = """
@@ -45,47 +46,50 @@ def fetchmail(fetchmailrc):
 
 
 def run(debug):
-    fetches = requests.get("http://admin/internal/fetch").json()
-    smtphost, smtpport = extract_host_port(os.environ.get("HOST_SMTP", "smtp"), None)
-    if smtpport is None:
-        smtphostport = smtphost
-    else:
-        smtphostport = "%s/%d" % (smtphost, smtpport)
-    for fetch in fetches:
-        fetchmailrc = ""
-        options = "options antispam 501, 504, 550, 553, 554"
-        options += " sslmode wrapped" if fetch["tls"] else ""
-        options += " keep" if fetch["keep"] else " fetchall"
-        fetchmailrc += RC_LINE.format(
-            user_email=escape_rc_string(fetch["user_email"]),
-            protocol=fetch["protocol"],
-            host=escape_rc_string(fetch["host"]),
-            port=fetch["port"],
-            smtphost=smtphostport,
-            username=escape_rc_string(fetch["username"]),
-            password=escape_rc_string(fetch["password"]),
-            options=options
-        )
-        if debug:
-            print(fetchmailrc)
-        try:
-            print(fetchmail(fetchmailrc))
-            error_message = ""
-        except subprocess.CalledProcessError as error:
-            error_message = error.output.decode("utf8")
-            # No mail is not an error
-            if not error_message.startswith("fetchmail: No mail"):
-                print(error_message)
-            user_info = "for %s at %s" % (fetch["user_email"], fetch["host"])
-            # Number of messages seen is not a error as well
-            if ("messages" in error_message and
-                    "(seen " in error_message and
-                    user_info in error_message):
-                print(error_message)
-        finally:
-            requests.post("http://admin/internal/fetch/{}".format(fetch["id"]),
-                json=error_message.split("\n")[0]
+    try:
+        fetches = requests.get("http://admin/internal/fetch").json()
+        smtphost, smtpport = extract_host_port(os.environ.get("HOST_SMTP", "smtp"), None)
+        if smtpport is None:
+            smtphostport = smtphost
+        else:
+            smtphostport = "%s/%d" % (smtphost, smtpport)
+        for fetch in fetches:
+            fetchmailrc = ""
+            options = "options antispam 501, 504, 550, 553, 554"
+            options += " sslmode wrapped" if fetch["tls"] else ""
+            options += " keep" if fetch["keep"] else " fetchall"
+            fetchmailrc += RC_LINE.format(
+                user_email=escape_rc_string(fetch["user_email"]),
+                protocol=fetch["protocol"],
+                host=escape_rc_string(fetch["host"]),
+                port=fetch["port"],
+                smtphost=smtphostport,
+                username=escape_rc_string(fetch["username"]),
+                password=escape_rc_string(fetch["password"]),
+                options=options
             )
+            if debug:
+                print(fetchmailrc)
+            try:
+                print(fetchmail(fetchmailrc))
+                error_message = ""
+            except subprocess.CalledProcessError as error:
+                error_message = error.output.decode("utf8")
+                # No mail is not an error
+                if not error_message.startswith("fetchmail: No mail"):
+                    print(error_message)
+                user_info = "for %s at %s" % (fetch["user_email"], fetch["host"])
+                # Number of messages seen is not a error as well
+                if ("messages" in error_message and
+                        "(seen " in error_message and
+                        user_info in error_message):
+                    print(error_message)
+            finally:
+                requests.post("http://admin/internal/fetch/{}".format(fetch["id"]),
+                    json=error_message.split("\n")[0]
+                )
+    except Exception:
+        traceback.print_exc()
 
 
 if __name__ == "__main__":


Test patch: