From b3a383d1519a51d3002ca54c262870034f15dc48 Mon Sep 17 00:00:00 2001 From: Sebastian Spaeth Date: Sat, 7 May 2011 18:39:13 +0200 Subject: [PATCH] accounts: handle OfflineImapError severity FOLDER Throw an OfflineImapError when SELECTing a folder is unsuccessful and bail out with a FOLDER serverity. In accounts.py catch all OfflineImapErrors and either just log the error and skip the folder or bubble it up if it's severe. Signed-off-by: Sebastian Spaeth Signed-off-by: Nicolas Sebrecht --- offlineimap/accounts.py | 7 +++++++ offlineimap/folder/IMAP.py | 6 +++++- offlineimap/imaplibutil.py | 12 ++++++++++-- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/offlineimap/accounts.py b/offlineimap/accounts.py index e4499fa..3e8fe18 100644 --- a/offlineimap/accounts.py +++ b/offlineimap/accounts.py @@ -393,6 +393,13 @@ def syncfolder(accountname, remoterepos, remotefolder, localrepos, localrepos.restore_atime() except (KeyboardInterrupt, SystemExit): raise + except OfflineImapError, e: + # bubble up severe Errors, skip folder otherwise + if e.severity > OfflineImapError.ERROR.FOLDER: + raise + else: + ui.warn("Aborting folder sync '%s' [acc: '%s']\nReason was: %s" %\ + (localfolder.name, accountname, e.reason)) except: ui.warn("ERROR in syncfolder for %s folder %s: %s" % \ (accountname,remotefolder.getvisiblename(), diff --git a/offlineimap/folder/IMAP.py b/offlineimap/folder/IMAP.py index 9f60ded..9c91ddd 100644 --- a/offlineimap/folder/IMAP.py +++ b/offlineimap/folder/IMAP.py @@ -43,9 +43,13 @@ class IMAPFolder(BaseFolder): def selectro(self, imapobj): """Select this folder when we do not need write access. + Prefer SELECT to EXAMINE if we can, since some servers (Courier) do not stabilize UID validity until the folder is - selected.""" + selected. + .. todo: Still valid? Needs verification + + :returns: raises :exc:`OfflineImapError` severity FOLDER on error""" try: imapobj.select(self.getfullname()) except imapobj.readonly: diff --git a/offlineimap/imaplibutil.py b/offlineimap/imaplibutil.py index 7c98fef..5faf036 100644 --- a/offlineimap/imaplibutil.py +++ b/offlineimap/imaplibutil.py @@ -23,8 +23,8 @@ import time import subprocess from offlineimap.ui import getglobalui import threading +from offlineimap import OfflineImapError from offlineimap.imaplib2 import * - # Import the symbols we need that aren't exported by default from offlineimap.imaplib2 import IMAP4_PORT, IMAP4_SSL_PORT, InternalDate, Mon2num @@ -43,6 +43,10 @@ class UsefulIMAPMixIn: return None def select(self, mailbox='INBOX', readonly=None, force = 0): + """Selects a mailbox on the IMAP server + + :returns: 'OK' on success, nothing if the folder was already + selected or raises an :exc:`OfflineImapError`""" if (not force) and self.getselectedfolder() == mailbox \ and self.is_readonly == readonly: # No change; return. @@ -51,7 +55,11 @@ class UsefulIMAPMixIn: del self.untagged_responses[:] result = self.__class__.__bases__[1].select(self, mailbox, readonly) if result[0] != 'OK': - raise ValueError, "Error from select: %s" % str(result) + #in case of error, bail out with OfflineImapError + errstr = "Error SELECTing mailbox '%s', server reply:\n%s" %\ + (mailbox, result) + severity = OfflineImapError.ERROR.FOLDER + raise OfflineImapError(errstr, severity) if self.getstate() == 'SELECTED': self.selectedfolder = mailbox else: