Exceptions in threads

IB borovik at hotmail.com
Thu Jan 24 12:53:40 EST 2002


"Alex Martelli" <aleax at aleax.it> wrote in message news:<a2p92c$cc8$1 at serv1.iunet.it>...
> "Dale Strickland-Clark" <dale at riverhall.NOTHANKS.co.uk> wrote in message
> news:s8805u47uglj367vmdn9iob40dtuv066su at 4ax.com...
> > Martin von Loewis <loewis at informatik.hu-berlin.de> wrote:
> >
> > Thanks for the repsonse. Pretty much as I expect, unfortunately.
> >
> > >
> > >How would you establish an exception handler by other means but code?
> >
> > I was kind of hoping for some undocumented onException() or onEnd()
> > methods that I could override. A bit of a long shot, I grant you.
> 
> Well, there IS sys.excepthook, but I think it's global, not per-thread.
> 
> 
> Alex

Hello, 

I run into a similar problem with exception handling in a worker
thread in Tkinter/Pmw based application. The situation was aggravated
by Win98 - when after exception you print to the console from Tkinter,
Python dies more often than not. Then due to Win98 pecularities you
have to restart system or Python wouldn't start anymore.

Also I noticed that nice exception handler that Pmw supplies does not
catch exceptions in the worker thread. So the sys.excepthook callback
does not propagate into the child threads. I could not find easy way
to force it into the thread, so instead I come up with a different
solution.

I had to make a class derived from Thread with function run()
overloaded so it catches all expetions in the target function - see
code below. Then it saves exception data coming from sys.exc_info()
and leaves the rest of the problem to the main thread. When the thread
stops, the main thread can detect that there was a problem checking if
my_thread.except_str. Then it is up to the main thread what to do with
the exception. If it throughs another exception, the sys.excpethook
will be the right one. Or you can just write silently to some error
log file.

Hope it helps
--Igor

--------------------------------------------------

import threading
import sys
import traceback

class SilentThread(threading.Thread):
    def __init__(self, target, args=(), kwargs={}): #no group, no
name, non-verbose
        threading.Thread.__init__(self)
        self.__target = target
        self.__args = args
        self.__kwargs = kwargs
        #silent exception handling variables:
        self.except_str = None

    def run(self):
        #catch all exceptions from the target funcion:
        try:
            if self.__target:
                apply(self.__target, self.__args, self.__kwargs)
        except:
            info = sys.exc_info() #tuple: type, value, traceback
            self.except_str = '\n\nException in thread '+
self.getName() +':\n\n'
            for line in traceback.format_exception(info[0], info[1],
info[2]):
                self.except_str += line

#test:        
if __name__ == '__main__':
    #non GUI test
    import time
    
    def testFunc():
        raise RuntimeError, 'test'
    
    t = SilentThread(target = testFunc)
    t.start()
    while t.isAlive():
        time.sleep(0.1)

    if t.except_str:
        print t.except_str



More information about the Python-list mailing list