[PATCH 1/3] Implement ui.error() and output them at end of offlinimap sync

Sebastian Spaeth Sebastian at SSpaeth.de
Thu Aug 11 11:22:34 BST 2011


Output all raised Exceptions error strings to the error log. If we are
in debug mode, we also output the traceback of the exception.

Save all exceptions that occur during the run time to a Queue and output
them all again when the offlineimap sync is finished.

Signed-off-by: Sebastian Spaeth <Sebastian at SSpaeth.de>
---
 offlineimap/ui/UIBase.py |   58 ++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 53 insertions(+), 5 deletions(-)

diff --git a/offlineimap/ui/UIBase.py b/offlineimap/ui/UIBase.py
index 5524579..c5f897f 100644
--- a/offlineimap/ui/UIBase.py
+++ b/offlineimap/ui/UIBase.py
@@ -21,6 +21,7 @@ import time
 import sys
 import traceback
 import threading
+from Queue import Queue
 import offlineimap
 
 debugtypes = {'':'Other offlineimap related sync messages',
@@ -47,7 +48,9 @@ class UIBase:
         s.debugmsglen = 50
         s.threadaccounts = {}
         s.logfile = None
-    
+        s.exc_queue = Queue()
+        """saves all occuring exceptions, so we can output them at the end"""
+
     ################################################## UTILS
     def _msg(s, msg):
         """Generic tool called when no other works."""
@@ -82,6 +85,39 @@ class UIBase:
         else:
             s._msg("WARNING: " + msg)
 
+    def error(self, exc, exc_traceback=None, msg=None):
+        """Log a message at severity level ERROR
+
+        Log Exception 'exc' to error log, possibly prepended by a preceding
+        error "msg", detailing at what point the error occurred.
+
+        In debug mode, we also output the full traceback that occurred
+        if one has been passed in via sys.exc_traceback.
+
+        Also save the Exception to a stack that can be output at the end
+        of the sync run when offlineiamp exits. It is recommended to
+        always pass in exceptions if possible, so we can give the user
+        the best debugging info.
+
+        One example of such a call might be:
+
+           ui.error(exc, sys.exc_traceback, msg="While syncing Folder %s in "
+                                                "repo %s")
+        """
+        cur_thread = threading.currentThread()
+        if msg:
+            self._msg("ERROR [%s]: %s\n  %s" % (cur_thread, msg, exc))
+        else:
+            self._msg("ERROR [%s]: %s" % (cur_thread, exc))
+
+        if not self.debuglist:
+            # only output tracebacks in debug mode
+            exc_traceback = None
+        # push exc on the queue for later output
+        self.exc_queue.put((msg, exc, exc_traceback))
+        if exc_traceback:
+            self._msg(traceback.format_tb(exc_traceback))
+
     def registerthread(s, account):
         """Provides a hint to UIs about which account this particular
         thread is processing."""
@@ -315,12 +351,24 @@ class UIBase:
     def mainException(s):
         s._msg(s.getMainExceptionString())
 
-    def terminate(s, exitstatus = 0, errortitle = None, errormsg = None):
+    def terminate(self, exitstatus = 0, errortitle = None, errormsg = None):
         """Called to terminate the application."""
-        if errormsg <> None:
-            if errortitle <> None:
-                sys.stderr.write('ERROR: %s\n\n%s\n'%(errortitle, errormsg))
+        #print any exceptions that have occurred over the run
+        if not self.exc_queue.empty():
+           self._msg("\nERROR: Exceptions occurred during the run!")
+        while not self.exc_queue.empty():
+            msg, exc, exc_traceback = self.exc_queue.get()
+            if msg:
+                self._msg("ERROR: %s\n  %s" % (msg, exc))
             else:
+                self._msg("ERROR: %s" % (exc))
+            if exc_traceback:
+                self._msg("\nTraceback:\n%s" %"".join(
+                        traceback.format_tb(exc_traceback)))
+
+        if errormsg and errortitle:
+            sys.stderr.write('ERROR: %s\n\n%s\n'%(errortitle, errormsg))
+        elif errormsg:
                 sys.stderr.write('%s\n' % errormsg)
         sys.exit(exitstatus)
 
-- 
1.7.4.1





More information about the OfflineIMAP-project mailing list