Note: there is one exact answer to my question in the duplicate (also see my answer below for the modified code). Thank you @quamrana for the pointer
Context: I have a list of methods in a class which are all started in threads. Some of these methods are expected to raise exceptions and these exceptions must be handled in the main program (= not in the method itself).
The problem: the exception is not caught and the interpretation (success / failure) is wrong as all threads are "successful".
What I thought would have worked: a try
/except
in which the thread is actually start()
.
Please note in the Traceback that both answers are (...) was successful
as if the try
only handled the mere fact of starting the thread (.start()
) and not what is happening in the thread itself.
import threading
class Checks:
@staticmethod
def isok():
print("OK")
@staticmethod
def isko():
raise Exception("KO")
# db will keep a map of method names in Check with the actual (executable) method
db = {}
# getting all the methods from Checks, without the built_in ones
for check in [k for k in dir(Checks) if not k.startswith('_')]:
# create a thread for the method
db[check] = threading.Thread(target=getattr(Checks, check))
try:
# start the thread
db[check].start()
except Exception:
print(f"{check} raised an exception")
else:
print(f"{check} was successful")
# wait for all the threads to be finished
for thread in db.keys():
db[thread].join()
# all the threads are finished at that point
print("all threads are done")
The output:
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Users\yop\AppData\Local\Programs\Python\Python37-32\lib\threading.py", line 926, in _bootstrap_inner
self.run()
File "C:\Users\yop\AppData\Local\Programs\Python\Python37-32\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "C:/Users/yop/.PyCharm2019.2/config/scratches/scratch_6.py", line 11, in isko
raise Exception("KO")
Exception: KO
isko was successful
OK
isok was successful
all threads are done
(the Traceback will be mixed with the actual output of the program, due to the threads but the sequence is always the same)
EDIT: following up on a comment I want to highlight again that the exceptions will occur in the methods but must be caught in the main program (= not handled in the methods themselves).
In a non-threaded approach it is easy: the try
/exception
clause in code similar to the one above would catch them as they bubble up.