From 58d34df29fc327dc8aa8ed79ef4ee1ee52bb58f9 Mon Sep 17 00:00:00 2001 From: Thomas De Schampheleire Date: Mon, 4 Jan 2021 10:10:34 +0100 Subject: [PATCH] imapserver: fix exception handling in xoauth2handler In case of an exception in XOAUTH2 code refresh (HTTP Error 400: Bad Request), following exception occurs: ERROR: While attempting to sync account 'xxx' __init__() missing 3 required positional arguments: 'msg', 'hdrs', and 'fp' Traceback: File ".../offlineimap3/offlineimap/accounts.py", line 298, in syncrunner self.__sync() File ".../offlineimap3/offlineimap/accounts.py", line 374, in __sync remoterepos.getfolders() File ".../offlineimap3/offlineimap/repository/IMAP.py", line 648, in getfolders imapobj = self.imapserver.acquireconnection() File ".../offlineimap3/offlineimap/imapserver.py", line 591, in acquireconnection self.__authn_helper(imapobj) File ".../offlineimap3/offlineimap/imapserver.py", line 448, in __authn_helper if func(imapobj): File ".../offlineimap3/offlineimap/imapserver.py", line 382, in __authn_xoauth2 imapobj.authenticate('XOAUTH2', self.__xoauth2handler) File ".../offlineimap3/venv/lib/python3.7/site-packages/imaplib2.py", line 682, in authenticate typ, dat = self._simple_command('AUTHENTICATE', mechanism.upper()) File ".../offlineimap3/venv/lib/python3.7/site-packages/imaplib2.py", line 1675, in _simple_command return self._command_complete(self._command(name, *args), kw) File ".../offlineimap3/venv/lib/python3.7/site-packages/imaplib2.py", line 1395, in _command literal = literator(data, rqb) File ".../offlineimap3/venv/lib/python3.7/site-packages/imaplib2.py", line 2238, in process ret = self.mech(self.decode(data)) File ".../offlineimap3/offlineimap/imapserver.py", line 257, in __xoauth2handler raise type(e)(msg, exc_info()[2]) The exception 'e' is of type HTTPError, which does not have the same kind of constructor as normal Python exceptions. Instead, print the constructed message and just raise the existing exception. With that change, the same condition triggers another problem further on: ERROR: While attempting to sync account 'xxx' tuple index out of range Traceback: File ".../offlineimap3/offlineimap/accounts.py", line 298, in syncrunner self.__sync() File ".../offlineimap3/offlineimap/accounts.py", line 374, in __sync remoterepos.getfolders() File ".../offlineimap3/offlineimap/repository/IMAP.py", line 648, in getfolders imapobj = self.imapserver.acquireconnection() File ".../offlineimap3/offlineimap/imapserver.py", line 664, in acquireconnection elif isinstance(e, socket.error) and e.args[0] == errno.ECONNREFUSED: because e.args is empty. --- offlineimap/imapserver.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/offlineimap/imapserver.py b/offlineimap/imapserver.py index 0812b3b..3970541 100644 --- a/offlineimap/imapserver.py +++ b/offlineimap/imapserver.py @@ -254,7 +254,8 @@ class IMAPServer: except Exception as eparams: msg = "%s [cannot display configuration: %s]" % (e, eparams) - raise type(e)(msg, exc_info()[2]) + self.ui.error(msg) + raise finally: socket.socket = original_socket @@ -660,7 +661,7 @@ class IMAPServer: % (self.hostname, self.repos, e) raise OfflineImapError(reason, severity, exc_info()[2]) - elif isinstance(e, socket.error) and e.args[0] == errno.ECONNREFUSED: + elif isinstance(e, socket.error) and e.args and e.args[0] == errno.ECONNREFUSED: # "Connection refused", can be a non-existing port, or an unauthorized # webproxy (open WLAN?) reason = "Connection to host '%s:%d' for repository '%s' was " \