Handle "no such user" more gracefully in client.py
Ever since I installed mailman3 on Debian Buster (so, yes, old version) I've been getting this from the daily cron jobs:
File "/usr/lib/python3/dist-packages/django_extensions/management/commands/runjobs.py", line 36, in runjobs
job().execute()
File "/usr/lib/python3/dist-packages/hyperkitty/jobs/sync_mailman.py", line 35, in execute
sync_with_mailman()
File "/usr/lib/python3/dist-packages/hyperkitty/lib/mailman.py", line 145, in sync_with_mailman
sender.set_mailman_id()
File "/usr/lib/python3/dist-packages/hyperkitty/models/sender.py", line 54, in set_mailman_id
mm_user = client.get_user(self.address)
File "/usr/lib/python3/dist-packages/mailmanclient/client.py", line 326, in get_user
return User(self._connection, content['self_link'], content)
KeyError: 'self_link'
This is because Client.get_user in client.py assumes that the users/<address>
look-up always returns a user. I imported my old mailman 2.x lists in the recommended manner and somehow ended up with emails where there's no valid member/user. This seems to cause the REST API to then return all users in a structure where they're in an array, rather than only a JSON object with a single user.
The upshot is that content['self_link']
doesn't exist, hence the trace above.
I've worked around this for now by adding a check:
if content.get('self_link', None) is None:
raise ValueError
This then gets caught by hyperkitty/models/sender.py set_mailman_id() causing the sender to get ignored.
In general client.py get_user needs to cater for the case where no user was found, rather than blindly assuming that a single user was found. I'm willing to allow that in a mailman3-only environment, with no import, this might be an impossible circumstance to reach, but it definitely is when you've imported lists from a mailman 2.x installation.