1

I created a script that runs several threads. Each thread runs a function in infinite loop. I would like to know if any of threads threw an exception.

Here is the basic structure how threads are started:

def main():
    VODP = Packager()
    WINSCP = WinSCP()
    threadList = []
    threadList.append(threading.Thread(target=VODP.scan))
    threadList.append(threading.Thread(target=WINSCP.ftp_sender))
    threadList.append(threading.Thread(target=WINSCP.ftp_status_checker))
    threadList.append(threading.Thread(target=WINSCP.synchronize))
    for thread in threadList:
        thread.start()
    for thread in threadList:
        thread.join()

main()

and here is a sample of a class with function in infinite loop:

class Packager:
    def __init__(self):
        self.rootDir, self.scanTime, self.extendedScanTime = self.configure_packager()
        self.foldersReadyToPack = []
    def scan(self):
        while True:
            if self.foldersReadyToPack == []:
                for dirpath, dirnames, filenames in os.walk(self.rootDir):
                    if(folder_verifier(dirpath)):
                        #print("Currently scanned folder: ", dirpath)
                        package_creator(dirpath)
                if len(self.foldersReadyToPack) > 0:
                    #print(f'Folders with suitable files has been found!')
                    packingQueue = PackingQueue(self.foldersReadyToPack)
                    packingQueue.execute_packing()
                    self.foldersReadyToPack = packingQueue.elements

How can I achieve that? How can get the information that thread has threw an exception and is no longer performing its tasks in infinite loop? I would like to get such information to pass it to class responsible for sending emails, when something suspicious occurs in program.

  • 1
    Please take a look at this topic, you might find it helpful since there a lot of ways how to get the result from a thread: https://stackoverflow.com/questions/6893968/how-to-get-the-return-value-from-a-thread-in-python (I'd recommend taking a look at `concurrent.futures`). – Gevorg Davoian Jul 24 '20 at 14:31

1 Answers1

1

You could use concurrent.futures:

import concurrent.futures


def foo_with_exc(a, b):
    raise ValueError()


def thread_starter():
    with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
        future = executor.submit(foo_with_exc, 1, 2)

        # Raise any exceptions raised by thread
        return future.result()


try:
    thread_starter()
except ValueError as e:
    print("Exception!")
alex_noname
  • 26,459
  • 5
  • 69
  • 86
  • So in my case, as the `foo_with_exc` fucntion is repeated infinitely, i should put `try` statement before `while True` and `except` statement with raising an error? Or should I put it during starting/joining threads? – warezsoftwarez Jul 27 '20 at 11:17