Python 3.8+threadingfunction
threading.excepthook()
errors in threads
The function called for an exception left unhandled in Thread.run(); replace it with your own, for example to send thread errors to a log.
Syntax
threading.excepthook = hook # def hook(args: threading.ExceptHookArgs)
An exception in a thread never reaches the main thread: join() returns as usual, the program carries on and the only trace is on stderr — easy to miss. Your own function in threading.excepthook catches such failures in every thread; sys.excepthook does not apply to threads. The hook runs in the failing thread and must not raise itself (sys.excepthook is called if it does); SystemExit is ignored silently by default. The original hook is kept in threading.__excepthook__. A concurrent.futures pool does not call the hook: the exception comes back from future.result().
Examples
# Python 3.10+
import threading
errors = []
def log_error(args):
errors.append(f'{args.thread.name}: {args.exc_type.__name__}: {args.exc_value}')
threading.excepthook = log_error
def job():
1 / 0
t = threading.Thread(target=job, name='calc')
t.start()
t.join()
threading.excepthook = threading.__excepthook__
print(errors) # → ['calc: ZeroDivisionError: division by zero']
import threading
def job():
raise ValueError('oops')
t = threading.Thread(target=job)
t.start()
t.join() # трассировка «Exception in thread ...» ушла в stderr
print('main is alive') # → main is alive
See also
Open in the full glossarydocs.python.orgReport an inaccuracy