How to catch a thread\'s exception in the caller thread in Python?

Python threads do not automatically pass exceptions to the caller thread. To catch thread exceptions in the main thread, you can use custom thread classes, the ThreadPoolExecutor with futures, or a shared queue.

Using a Custom Thread Class

The easiest way to catch exceptions in a thread is to create a custom thread class that stores any exceptions in an instance variable. After the thread finishes, you can check whether an exception occurred ?

import threading

class ThreadWithException(threading.Thread):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.exception = None

    def run(self):
        try:
            if self._target:
                self._target(*self._args, **self._kwargs)
        except Exception as e:
            self.exception = e

def task():
    raise ValueError("An error occurred in the thread")

thread = ThreadWithException(target=task)
thread.start()
thread.join()

if thread.exception:
    print("Caught exception from thread:", thread.exception)

The output of the above code is ?

Caught exception from thread: An error occurred in the thread

Using concurrent.futures.ThreadPoolExecutor

The ThreadPoolExecutor from the concurrent.futures module provides a structured way to handle exceptions. The returned Future object allows you to check for errors after the thread completes ?

from concurrent.futures import ThreadPoolExecutor

def task():
    raise RuntimeError("Something went wrong")

with ThreadPoolExecutor() as executor:
    future = executor.submit(task)
    try:
        result = future.result()
    except Exception as e:
        print("Caught exception from thread:", e)

The output of the above code is ?

Caught exception from thread: Something went wrong

Using a Shared Queue

Another approach is using a queue.Queue to pass exceptions from threads to the main thread. This method is particularly useful when multiple threads need to report exceptions ?

import threading
import queue

def task(q):
    try:
        raise ZeroDivisionError("Division by zero")
    except Exception as e:
        q.put(e)

q = queue.Queue()
thread = threading.Thread(target=task, args=(q,))
thread.start()
thread.join()

if not q.empty():
    error = q.get()
    print("Caught exception from thread:", error)

The output of the above code is ?

Caught exception from thread: Division by zero

Comparison

Method Best For Complexity
Custom Thread Class Single thread exception handling Medium
ThreadPoolExecutor Professional thread management Low
Shared Queue Multiple threads reporting errors Medium

Conclusion

Use ThreadPoolExecutor for professional thread management with built-in exception handling. For custom control, use a custom thread class or shared queue approach based on your specific needs.

Updated on: 2026-03-24T16:29:42+05:30

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements