1

Possible Duplicate:
Catch a thread’s exception in the caller thread in Python

I have a given code and there is a

thread.start_new_thread()

As I just read in python doc: "When the function terminates with an unhandled exception, a stack trace is printed and then the thread exits (but other threads continue to run)." But I want to terminate also the main-thread when the (new) function terminates with an exception - So the exception shall be transfered to the main-thread. How can I do this?

edit: here is part of my code:

def CaptureRegionAsync(region=SCREEN, name="Region", asyncDelay=None, subDir="de"):
    if asyncDelay is None:
        CaptureRegion(region, name, subDir)
    else:
        thread.start_new_thread(_CaptureRegionAsync, (region, name, asyncDelay, subDir))

def _CaptureRegionAsync(region, name, asyncDelay, subDir):
    time.sleep(max(0, asyncDelay))
    CaptureRegion(region, name, subDir)

def CaptureRegion(region=SCREEN, name="Region", subDir="de"):
    ...
    if found:
        return
    else:
        raise Exception(u"[warn] Screenshot has changed: %s" % filename)

CaptureRegionAsync(myregion,"name",2)
Community
  • 1
  • 1
Munchkin
  • 4,528
  • 7
  • 45
  • 93
  • Seems another problem to me, not a duplicate. If "a given code" means "third-party code that can not be modified", the problem is totally different. – Ellioh Jan 14 '13 at 10:14
  • Sorry, "a given code" means that I didn't write it and so I'm not very familiar with it - but I can modify it. – Munchkin Jan 14 '13 at 10:24
  • Then my first answer is not to your question, and monkey patching thread is a bad idea. :-) – Ellioh Jan 14 '13 at 10:28

1 Answers1

0

UPD: It is not the best solution as your question is different from what I thought it is: I expected you were trying to deal with an exception in thread code you can not modify. However, i decided not to delete the answer.

It's hard to catch an exception from another thread. Usually it should be transferred manually.

Can you wrap a thread function? If you wrap the worker thread that crashes into try...except, then you may perform actions needed to exit main thread in except block (sys.exit seems to be useless, though it's a surprise to me, but there is thread.interrupt_main() and os.abort(), though you may need something more graceful like setting a flag the main thread is checking regularly).

However, if you can not wrap the function (can not modify the third-party code calling start_new_thread), you may try monkey patching the thread module (or the third-party module itself). Patched version of start_new_thread() should wrap the function you worry about:

import thread
import sys
import time

def t():
    print "Thread started"
    raise Exception("t Kaboom")

def t1():
    print "Thread started"
    raise Exception("t1 Kaboom")


def decorate(s_n_t):
    def decorated(f, a, kw={}):
        if f != t:
            return s_n_t(f, a, kw)
        def thunk(*args, **kwargs):
            try:
                f(*args, **kwargs)
            except:
                print "Kaboom"
                thread.interrupt_main() # or os.abort()
        return s_n_t(thunk, a, kw)
    return decorated

# Now let's do monkey patching:
thread.start_new_thread = decorate(thread.start_new_thread)

thread.start_new_thread(t1, ())
time.sleep(5)
thread.start_new_thread(t, ())
time.sleep(5)

Here an exception in t() causes thread.interrupt_main()/os.abort(). Other thread functions in the application are not affected.

Ellioh
  • 5,162
  • 2
  • 20
  • 33
  • Thanks for your answer! sys.exit() in the new_thread doesn't kill the main-thread: "sys.exit() [...] will only exit the process when called from the main thread [...]" (http://docs.python.org/2/library/sys.html) So it does not work for me. I edited my first post and added a part of my code. – Munchkin Jan 14 '13 at 13:03
  • Wow... really, it itself raises an exception... – Ellioh Jan 14 '13 at 13:07
  • Fixed it to use thread.interrupt_main() – Ellioh Jan 14 '13 at 13:13