The problem is that thread_obj.start() returns immediately. The child thread that you started executes in its own context, in its own stack. Any exception that occurs there is in the context of the child thread. You have to communicate this information to the parent thread by passing some message.
The code can be re-written as follows:
import sys import threading import Queue class ExcThread(threading.Thread): def __init__(self, foo): threading.Thread.__init__(self) self.foo = foo def run(self): try: raise Exception('An error occurred here.') except Exception: self.foo.put(sys.exc_info()) def main(): foo = Queue.Queue() thread_obj = ExcThread(foo) thread_obj.start() while True: try: exc = foo.get(block=False) except Queue.Empty: pass else: exc_type, exc_obj, exc_trace = exc print exc_type, exc_obj print exc_trace thread_obj.join(0.1) if thread_obj.isAlive(): continue