Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Raise unhandled exceptions in a thread in the main thread? [duplicate]

There are some similar questions, but none supply the answer I require.

If I create threads via threading.Thread, which then throw exceptions which are unhandled, those threads are terminated. I wish to retain the default print out of the exception details with the stack trace, but bring down the whole process as well.

I've considered that it might be possible to catch all exceptions in the threads, and reraise them on the main thread object, or perhaps it's possible to manually perform the default exception handling, and then raise a SystemExit on the main thread.

What's the best way to go about this?

like image 850
Matt Joiner Avatar asked Dec 06 '09 03:12

Matt Joiner


People also ask

How do you handle an unhandled exception in the thread?

Uncaught exception handler will be used to demonstrate the use of exception with thread. It is a specific interface provided by Java to handle exception in the thread run method. There are two methods to create a thread: Extend the thread Class (java.

What happens when an exception occurs in a thread?

If an unhandled exception occurs in the main thread of an application, the main thread terminates, along with your entire application. An unhandled exception in a spawned worker thread, however, will terminate only that thread.

What happens when an exception occurs in a thread python?

Technical details of this implementation: when the child thread throws an exception, it is passed to the parent through a Queue and thrown again in the parent thread.

How do you catch an exception in a thread?

Thread Exception in Java | Exception in Thread. Thread Exception in Java | When we call a sleep() method in a Java program, it must be enclosed in try block and followed by catch block. This is because sleep() method throws an exception named InterruptedException that should be caught.


2 Answers

I wrote about Re-throwing exceptions in Python, including something very much like this as an example.

On your worker thread you do this (Python 3.x, see below for Python 2.x version):

try:
    self.result = self.do_something_dangerous()
except Exception as e:
    import sys
    self.exc_info = sys.exc_info()

and on your main thread:

if self.exc_info:
    raise self.exc_info[1].with_traceback(self.exc_info[2])
return self.result

Python 2.x:

try:
    self.result = self.do_something_dangerous()
except Exception, e:
    import sys
    self.exc_info = sys.exc_info()

and on your main thread you do this:

if self.exc_info:
    raise self.exc_info[1], None, self.exc_info[2]
return self.result

The exception will appear in the main thread just as if it had been raised in the worker thread.

like image 82
Ned Batchelder Avatar answered Sep 28 '22 08:09

Ned Batchelder


The only exception a secondary thread can reliably raise in the main thread is KeyboardInterrupt: the way the secondary thread does it is by calling the function thread.interrupt_main(). There is no way to associate extra info (about the reason for the exception) with the exception object that gets raised -- the latter's always just a plain KeyboardInterrupt. So, you need to stash that information away somewhere else, e.g. on a dedicated instance of Queue.Queue -- that info might include the results the secondary thread can get via sys.exc_info(), and anything else you find useful of course.

The main thread will need to recover that extra info (and take into account that the queue will be empty if the keyboard interrupt is actually due to the user hitting control-C or the like, so, use get_nowait and be ready to deal with a Queue.Empty exception, for example), format it however you desire, and terminate (if all secondary threads are daemons, the whole process terminates when the main thread terminates).

like image 42
Alex Martelli Avatar answered Sep 28 '22 08:09

Alex Martelli