/offlineimap/head: changeset 272

When an exception occurs, OfflineIMAP will attempt to print the last
50 debug messages, whether or not debugging was enabled for this
session. This way, even unexpected and non-repeatable errors stand a
chance of getting a more detailed log.
This commit is contained in:
jgoerzen 2002-10-17 00:27:27 +01:00
parent 434233d8c4
commit 09a2ac9221
3 changed files with 54 additions and 16 deletions

View File

@ -1,6 +1,10 @@
offlineimap (3.99.2) unstable; urgency=low offlineimap (3.99.2) unstable; urgency=low
* Further attempts to fix imapsplit problems. * Further attempts to fix imapsplit problems.
* When an exception occurs, OfflineIMAP will attempt to print the last
50 debug messages, whether or not debugging was enabled for this
session. This way, even unexpected and non-repeatable errors stand
a chance of getting a more detailed log.
-- John Goerzen <jgoerzen@complete.org> Tue, 15 Oct 2002 12:35:42 -0500 -- John Goerzen <jgoerzen@complete.org> Tue, 15 Oct 2002 12:35:42 -0500

View File

@ -207,6 +207,7 @@ class VerboseUI(UIBase):
s.availablethreadframes.append(tf) s.availablethreadframes.append(tf)
del s.threadframes[threadid] del s.threadframes[threadid]
s.tflock.release() s.tflock.release()
UIBase.threadExited(s, thread)
def idlevacuum(s): def idlevacuum(s):
while s.notdeleted: while s.notdeleted:
@ -218,24 +219,22 @@ class VerboseUI(UIBase):
s.tflock.release() s.tflock.release()
def threadException(s, thread): def threadException(s, thread):
msg = "Thread '%s' terminated with exception:\n%s" % \ exceptionstr = s.getThreadExceptionString(thread)
(thread.getName(), thread.getExitStackTrace()) print exceptionstr
print msg
s.top.destroy() s.top.destroy()
s.top = None s.top = None
TextOKDialog("Thread Exception", msg) TextOKDialog("Thread Exception", exceptionstr)
s.delThreadDebugLog(thread)
s.terminate(100) s.terminate(100)
def mainException(s): def mainException(s):
sbuf = StringIO() exceptionstr = s.getMainExceptionString()
traceback.print_exc(file = sbuf) print exceptionstr
msg = "Main program terminated with exception:\n" + sbuf.getvalue()
print msg
s.top.destroy() s.top.destroy()
s.top = None s.top = None
TextOKDialog("Main Program Exception", msg) TextOKDialog("Main Program Exception", exceptionstr)
def warn(s, msg): def warn(s, msg):
TextOKDialog("OfflineIMAP Warning", msg) TextOKDialog("OfflineIMAP Warning", msg)

View File

@ -17,7 +17,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
import offlineimap.version import offlineimap.version
import re, time, sys, traceback import re, time, sys, traceback, threading
from StringIO import StringIO from StringIO import StringIO
debugtypes = {'imap': 'IMAP protocol debugging', debugtypes = {'imap': 'IMAP protocol debugging',
@ -36,6 +36,8 @@ class UIBase:
s.verbose = verbose s.verbose = verbose
s.config = config s.config = config
s.debuglist = [] s.debuglist = []
s.debugmessages = {}
s.debugmsglen = 50
################################################## UTILS ################################################## UTILS
def _msg(s, msg): def _msg(s, msg):
@ -46,6 +48,15 @@ class UIBase:
s._msg("WARNING: " + msg) s._msg("WARNING: " + msg)
def debug(s, debugtype, msg): def debug(s, debugtype, msg):
thisthread = threading.currentThread()
if s.debugmessages.has_key(thisthread):
s.debugmessages[thisthread].append("%s: %s" % (debugtype, msg))
else:
s.debugmessages[thisthread] = ["%s: %s" % (debugtype, msg)]
while len(s.debugmessages[thisthread]) > s.debugmsglen:
s.debugmessages[thisthread] = s.debugmessages[thisthread][1:]
if debugtype in s.debuglist: if debugtype in s.debuglist:
s._msg("DEBUG[%s]: %s" % (debugtype, msg)) s._msg("DEBUG[%s]: %s" % (debugtype, msg))
@ -195,18 +206,42 @@ class UIBase:
################################################## Threads ################################################## Threads
def getThreadDebugLog(s, thread):
if s.debugmessages.has_key(thread):
message = "\nLast %d debug messages logged for %s prior to exception:\n"\
% (len(s.debugmessages[thread]), thread.getName())
message += "\n".join(s.debugmessages[thread])
else:
message = "\nNo debug messages were logged for %s." % \
thread.getName()
return message
def delThreadDebugLog(s, thread):
if s.debugmessages.has_key(thread):
del s.debugmessages[thread]
def getThreadExceptionString(s, thread):
message = "Thread '%s' terminated with exception:\n%s" % \
(thread.getName(), thread.getExitStackTrace())
message += "\n" + s.getThreadDebugLog(thread)
return message
def threadException(s, thread): def threadException(s, thread):
"""Called when a thread has terminated with an exception. """Called when a thread has terminated with an exception.
The argument is the ExitNotifyThread that has so terminated.""" The argument is the ExitNotifyThread that has so terminated."""
s._msg("Thread '%s' terminated with exception:\n%s" % \ s._msg(s.getThreadExceptionString(thread))
(thread.getName(), thread.getExitStackTrace())) s.delThreadDebugLog(thread)
s.terminate(100) s.terminate(100)
def mainException(s): def getMainExceptionString(s):
sbuf = StringIO() sbuf = StringIO()
traceback.print_exc(file = sbuf) traceback.print_exc(file = sbuf)
s._msg("Main program terminated with exception:\n" + return "Main program terminated with exception:\n" + \
sbuf.getvalue()) sbuf.getvalue() + "\n" + \
s.getThreadDebugLog(threading.currentThread())
def mainException(s):
s._msg(s.getMainExceptionString())
def terminate(s, exitstatus = 0): def terminate(s, exitstatus = 0):
"""Called to terminate the application.""" """Called to terminate the application."""
@ -215,7 +250,7 @@ class UIBase:
def threadExited(s, thread): def threadExited(s, thread):
"""Called when a thread has exited normally. Many UIs will """Called when a thread has exited normally. Many UIs will
just ignore this.""" just ignore this."""
pass s.delThreadDebugLog(thread)
################################################## Other ################################################## Other