Asyncio, threadpoolexecutor can do this well (Python threading needs a hack).
https://superfastpython.com/threadpoolexecutor-exception-handling/#Exception_Handling_in_Callbacks
The best is to use a callback like this
def exception_call(fut):
fut.result()
[fut.add_done_callback(exception_call) for fut in self.futs]
The callback is always called individually regardless of success or exceptions.
fut.result() will re-create the exception from the thread in the main.
fut.exception() can alternatively show no traceback, but just exception info
Asyncio, threadpoolexecutor can do this well (Python threading needs a hack).
https://superfastpython.com/threadpoolexecutor-exception-handling/#Exception_Handling_in_Callbacks
The best is to use a callback like this
The callback is always called individually regardless of success or exceptions.
fut.result() will re-create the exception from the thread in the main.
fut.exception() can alternatively show no traceback, but just exception info