deltachat / mailadm

mail account administration tool for temporary and other account creation/modification
https://mailadm.readthedocs.io/
Mozilla Public License 2.0
13 stars 1 forks source link

Bot takes down /new_email API endpoint due to mailcow error #112

Open link2xt opened 1 year ago

link2xt commented 1 year ago

Here is the backtrace:

Traceback (most recent call last):
  File "/usr/lib/python3.9/site-packages/mailadm/bot.py", line 270, in main
    for logmsg in prune(mailadm_db).get("message"):
  File "/usr/lib/python3.9/site-packages/mailadm/commands.py", line 84, in prune
    conn.get_mailcow_connection().del_user_mailcow(user_info.addr)
  File "/usr/lib/python3.9/site-packages/mailadm/mailcow.py", line 51, in del_user_mailcow
    json = result.json()
  File "/usr/lib/python3.9/site-packages/requests/models.py", line 910, in json
    return complexjson.loads(self.text, **kwargs)
  File "/usr/lib/python3.9/json/__init__.py", line 346, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.9/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.9/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

The whole container stops, because delete/mailbox returns an HTTP 200 response with this contents:

<center style='font-family:sans-serif;'>Connection to Redis failed.<br /><br />The following error was reported:<br/>php_network_getaddresses: getaddrinfo for redis-mailcow failed: Name does not resolve</center>

The exception in json = result.json() inside del_user_mailcow() should be handled somehow. Given that del_user_mailcow() throws a MailcowError exception when there is a proper error, probably there should be an exception handler around the whole del_user_mailcow() call.

I did a quick fix on the server for now:

diff --git a/src/mailadm/commands.py b/src/mailadm/commands.py
index ac09ff7..9afa607 100644
--- a/src/mailadm/commands.py
+++ b/src/mailadm/commands.py
@@ -5,6 +5,8 @@ from mailadm.gen_qr import gen_qr
 from mailadm.mailcow import MailcowError
 from mailadm.util import get_human_readable_id

+from json.decoder import JSONDecodeError
+

 def add_token(db, name, expiry, maxuse, prefix, token) -> dict:
     """Adds a token to create users"""
@@ -84,7 +86,7 @@ def prune(db, dryrun=False) -> {}:
                     conn.get_mailcow_connection().del_user_mailcow(user_info.addr)
                 with db.write_transaction() as conn:
                     conn.del_user_db(user_info.addr)
-            except (DBError, MailcowError) as e:
+            except (JSONDecodeError, DBError, MailcowError) as e:
                 result["status"] = "error"
                 result["message"].append("failed to delete account %s: %s" % (user_info.addr, e))
                 continue
link2xt commented 1 year ago

I think all exceptions should be handled, but in case of unknown errors they should be only logged but not be returned as they may contain the information we don't want to leak, like this redis-mailcow hostname.

link2xt commented 1 year ago

This is also part of the larger problem #78. It would be ok for the bot to crash, but it currently takes down the /new_email API which could otherwise start working once the backend problem resolves.