Recently, while working on a project, I encountered a problem where the main thread was unable to catch an exception thrown in a child thread.
Let's start with the definition of a thread class
''''' Created on Oct 27, 2015 @author: wujz ''' import threading class runScriptThread(): def __init__(self, funcName, *args): .__init__(self) = args = funcName def run(self): try: (*()) except Exception as e: raise e
It's simple, pass in the method to be called and enable a new thread to run the method.
In the main thread, start an object of this thread class, it is necessary to declare an object and then start on it, the example is as follows
import runScriptThread,traceback if __name__=='__main__': sth = 'hello world' try: aChildThread = runScriptThread(printSth, sth) () () except Exception as e: print(str(traceback.format_exc()))
But with such code, the main method can't catch the exception in the subthread because the start() method will open a new stack for the subthread, and the main method's stack therefore can't catch the exception.
The solution is very simple, that is, by setting a member variable of whether the thread exits abnormally or not flag, when the thread exits abnormally, make a flag on it. Then in the main thread to check the value of the flag bit after the end of the thread, if the exception, and then through the sys and traceback back to the exception information, and then thrown can be. The rewritten exception class:
''''' Created on Oct 27, 2015 @author: wujz ''' import threading,traceback,sys class runScriptThread(): #The timer class is derived from the class def __init__(self, funcName, *args): .__init__(self) = args = funcName = 0 = None self.exc_traceback = '' def run(self): #Overwrite run() method, put what you want the thread do here try: self._run() except Exception as e: = 1 # Set this flag bit to 1 if the thread exits abnormally, 0 for normal exit = e self.exc_traceback = ''.join(traceback.format_exception(*sys.exc_info())) # Logging exceptions in changed member variables def _run(self): try: (*()) except Exception as e: raise e
Rewritten main thread:
import runScriptThread,traceback if __name__=='__main__': sth = 'hello world' try: aChildThread = runScriptThread(printSth, sth) () () except Exception as e: print(aChildThread.exc_traceback)
All of the above is the entire content of this post.