[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