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 Wrapper with threading.Thread

The easiest way to catch exceptions in a thread is to wrap the target function in a try-except block. You can then store the exception in a shared variable or object so it can be checked later from the main thread.

Example

In this example, we create a custom thread class that stores any exceptions in an instance variable. After the thread finishes running, we manually check whether an exception occurred inside the thread or not -

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)

Following is the output obtained -

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. You can use the returned Future object to check for errors after the thread has completed.

Example

In the following example, we submit a task that raises an exception and catch it using future.result(). This is the recommended way to handle exceptions when working with threads through executors -

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)

We get the output as shown below -

Caught exception from thread: Something went wrong

Using a Shared Queue to Report Exceptions

Another way to handle exceptions in threads is by using a queue.Queue. The thread can put any exceptions into the queue, and the main thread can read from it to check for errors.

Using a queue is useful when multiple threads need to report exceptions back to the main thread.

Example

In this example, the thread puts any exception into the queue, and the main thread checks the queue afterward -

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 error obtained is as shown below -

Caught exception from thread: Division by zero
Updated on: 2025-06-02T15:39:16+05:30

805 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements