Skip to content

Instantly share code, notes, and snippets.

@bsphere
Last active November 17, 2022 15:01
Show Gist options
  • Save bsphere/f1e0a7d033dab2871c5c to your computer and use it in GitHub Desktop.
Save bsphere/f1e0a7d033dab2871c5c to your computer and use it in GitHub Desktop.
How to catch exceptions raised by Python worker threads
import Queue
import threading
class WorkerThread(threading.Thread):
def __init__(self, q):
super(WorkerThread, self).__init__()
self q = q
self.exception = None
def run():
try:
while not self.q.empty():
item = None
try:
item = self.q.get(False)
# do your stuff
except Queue.Empty:
pass
finally:
if item:
self.q.task_done()
except Exception as e:
self.exception = e
def get_exception():
return self.exception
class MyClass:
def spawn_threads(self, q):
self.threads = []
for _ in range(NUM_THREADS):
t = WorkerThread(q)
self.threads,append(t)
t.start()
def raise_thread_exceptions():
for t in self.threads:
e = t.get_exception()
if e:
raise e
def my_func(self):
q = Queue.Queue()
# do something and q.put()
self.spawn_threads(q)
q.join()
# raise exceptions from worker threads
self.raise_thread_exceptions()
@eladweiss
Copy link

Brilliant. Thanks.

@iFA88
Copy link

iFA88 commented Apr 5, 2018

L38: self.threads.append(t)

@ihadanny
Copy link

ihadanny commented Nov 4, 2018

L8: self.q = q

@ihadanny
Copy link

ihadanny commented Nov 7, 2018

there's a bug here when all threads are thrown and the q still isn't empty.
L55 should be:

for t in threads: t.join()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment