How to get a raised exception from other thread

Peter Hansen peter at engcorp.com
Tue Oct 18 22:38:32 EDT 2005


dcrespo wrote:
>>Before, after, or during the .start() call, or somewhere else?
> I'd like to catch *just after* the .start() call.

Excellent.  That makes it pretty easy then, since even though you are 
spawning a thread to do the work, your main thread isn't expected to 
continue processing in parallel.  See my draft solution below.  If it 
doesn't seem to suit, explain where it fails you and we can try to 
evolve it (assuming we're on the same page at all here).

> When you specify the case number 2, the IP must be valid for the
> computer where the program runs, otherwise, it raises an exception
> saying that "Can't assign requested address".
> 
> MainProgram.py
> ...
> SrvrTCP = module.ThreadedTCPServer(ip,port)
> SrvrTCP.start()
 > #Here, I want to know if the TCPServer started well.

Leave that part as it is.  We'll override the start() method in your 
subclass to solve your problem.

> module.py
> ...
> class ThreadedTCPServer(threading.Thread):
> 
>     def __init__(self, ip,port):
>         threading.Thread.__init__(self)
>         self.ip= ip
>         self.port= port
           self.startError = None
           self.startedEvent = threading.Event()


       def start(self):
           '''start thread and wait for successful start'''
           threading.Thread.start(self)
           self.startedEvent.wait()
           if self.startError:
               raise self.startError


>     def run(self):
>         TCPServer((self.ip,self.port)) #Here, if the self.ip is
> invalid, it raises an exception.
> ...

We have to change the run() method slightly now:

       def run(self):
           try:
               try:
                   TCPServer((self.ip, self.port))
               except Exception, ex:
                   self.startError = ex
                   return
           finally:
               self.startedEvent.set()

           # do the rest of the existing run() code here


Now that may not be perfect, since I'm not familiar with the TCPServer() 
call.  I've sort of assumed it does something quickly and returns, or 
raises an exception if the input is bad.  If it doesn't actually return 
if it starts successfully, you would need a little different approach. 
Probably adding a simple timeout to the self.startEvent.wait() call 
would work.

Note also that you don't get the full original traceback with this 
technique.  I'm not sure you can, actually (though I can imagine that 
with Python one could "stitch together" a traceback from a previous 
exception as one raises a new exception).  From what you describe, 
however, it sounds like you just need to know that the exception 
occurred, not the precise line of code down in TCPServer() where it was 
originally raised.

I hope that helps and/or gives you some leads on a better solution.

-Peter



More information about the Python-list mailing list