1

I have some code that is multi-threaded and any time I introduce a bug in any non-main thread, that thread fails silently, and that makes it difficult to debug the program. What is the best way to handle exceptions in threads that aren't the main thread? Ideally I just want uncaught exceptions to kill the process like they would in the main thread.

For example in this code the result will never be changed because I try to reference a function on an object that is set to None:

from threading import Thread

def thread_func(args):
    global result
    bad_obj = None
    bad_obj.call_function() # Should cause error
    result = 2

result = 1
thread = Thread(target=thread_func, args=None)
thread.start()
while True:
    print(result)

I really would prefer not to surround the entire thread function in a try catch, is there a way to make uncaught exceptions non silent at least?

Alexis Winters
  • 487
  • 1
  • 5
  • 18

1 Answers1

3

Thread class catches exceptions in the child thread and only reports them when Thread.join is called.

One work-around is to override Thread.run method in a derived class and use that instead of Thread:

from threading import Thread
import sys
import os

class MyThread(Thread):
    def run(self):
        try:
            super(MyThread, self).run()
        except Exception as e:
            print("error:", e, file=sys.stderr)
            os._exit(1)

Note that it uses os._exit because sys.exit works by throwing SystemExit exception and that doesn't terminate the process until Thread.join is called.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • This is a solid solution, is it possible to put this in class decorator? ``` @exit_on_exception class MyThread: ... ``` – GordanTrevis Feb 14 '22 at 21:45