
Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
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