Allow re-syncronization with main, allow “returning something” to main. The join() function of a thread actually runs in the caller’s thread - the main() thread.
This is an example of:
- printing a thread exception and traceback in the thread
- then passing the exception back to the main via the join()
$ ./handle_thread_exception_in_main.py
09:26:47: Thread-1 Causing an exception in thread
09:26:47: Thread-1: Printing traceback in the thread exception handler
File "/usr/lib/python3.7/threading.py", line 885, in _bootstrap
self._bootstrap_inner()
File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner
self.run()
File "./handle_thread_exception_in_main.py", line 30, in run
traceback.print_stack()
09:26:47: MainThread: re-raising exception in thread.join()
09:26:47: Exception Handled in Main, Details of the Exception: division by zero
The program:
#!/usr/bin/env python3
# Handle a thread exception in the main
# Importing the modules
import threading
import traceback
import logging
# Custom Thread Class
class MyThread(threading.Thread):
# Function that raises the exception
def someFunction(self):
name = threading.current_thread().name
logging.info("%s Causing an exception in thread ",name)
divbyzero=1/0
def run(self):
# Variable that stores the exception, if raised by someFunction
self.exc = None
try:
self.someFunction()
except Exception as e:
name = threading.current_thread().name
logging.info("%s: Printing traceback in the thread exception handler")
traceback.print_stack()
# now save the exception for later re-raising to the main
self.exc = e
def join(self):
threading.Thread.join(self)
# Since join() returns in caller thread
# we re-raise the caught exception
# if any was caught
if self.exc:
name = threading.current_thread().name
logging.info("%s: re-raising exception in thread.join()", name)
raise self.exc
# MAIN function
def main():
# set up logger
format = "%(asctime)s: %(message)s"
logging.basicConfig(format=format, level=logging.INFO,
datefmt="%H:%M:%S")
# Create a new Thread t
# Here Main is the caller thread
t = MyThread()
t.start()
# Exception handled in main thread
try:
t.join()
except Exception as e:
logging.info("Exception Handled in Main, Details of the Exception: %s", e)
if __name__ == '__main__':
main()