diff --git a/Changelog.draft.rst b/Changelog.draft.rst index fd445ac..3d20bcf 100644 --- a/Changelog.draft.rst +++ b/Changelog.draft.rst @@ -20,6 +20,9 @@ Bug Fixes --------- +* We protect more robustly against asking for inexistent messages from the + IMAP server, when someone else deletes or moves messages while we sync. + Pending for the next major release ================================== diff --git a/offlineimap/folder/IMAP.py b/offlineimap/folder/IMAP.py index 8851b5b..62f220f 100644 --- a/offlineimap/folder/IMAP.py +++ b/offlineimap/folder/IMAP.py @@ -23,7 +23,7 @@ import re import time from copy import copy from Base import BaseFolder -from offlineimap import imaputil, imaplibutil +from offlineimap import imaputil, imaplibutil, OfflineImapError class IMAPFolder(BaseFolder): def __init__(self, imapserver, name, visiblename, accountname, repository): @@ -195,13 +195,24 @@ class IMAPFolder(BaseFolder): def getmessage(self, uid): """Retrieve message with UID from the IMAP server (incl body) - :returns: the message body + :returns: the message body or throws and OfflineImapError + (probably severity MESSAGE) if e.g. no message with + this UID could be found. """ imapobj = self.imapserver.acquireconnection() try: imapobj.select(self.getfullname(), readonly = 1) - res_type, data = imapobj.uid('fetch', '%d' % uid, '(BODY.PEEK[])') - assert res_type == 'OK', "Fetching message with UID '%d' failed" % uid + res_type, data = imapobj.uid('fetch', str(uid), '(BODY.PEEK[])') + if data == [None] or res_type != 'OK': + #IMAP server says bad request or UID does not exist + severity = OfflineImapError.ERROR.MESSAGE + reason = "IMAP server '%s' responded with '%s' to fetching "\ + "message UID '%d'" % (self.getrepository(), res_type, uid) + if data == [None]: + #IMAP server did not find a message with this UID + reason = "IMAP server '%s' does not have a message "\ + "with UID '%s'" % (self.getrepository(), uid) + raise OfflineImapError(reason, severity) # data looks now e.g. [('320 (UID 17061 BODY[] # {2565}','msgbody....')] we only asked for one message, # and that msg is in data[0]. msbody is in [0][1] diff --git a/offlineimap/imapserver.py b/offlineimap/imapserver.py index 0aaeca6..1eb8f6b 100644 --- a/offlineimap/imapserver.py +++ b/offlineimap/imapserver.py @@ -301,7 +301,7 @@ class IMAPServer: (self.hostname, self.reposname) raise OfflineImapError(reason, severity) - elif isinstance(e, SSLError) and e.errno == 1: + elif SSLError and isinstance(e, SSLError) and e.errno == 1: # SSL unknown protocol error # happens e.g. when connecting via SSL to a non-SSL service if self.port != 443: