[master][PATCH] Allow catching exceptions from threads

Vratislav Podzimek vpodzime at redhat.com
Mon Dec 9 16:50:37 UTC 2013


By running exception handler every time an exception appears in a thread we
block us from using our features provided by the wait method. Some exceptions
may be non-critical and the waiting thread may recover from the erroneous state.
However, we need to give it a chance to do so.

The wait_all method called before we start the actual installation should make
sure there are no abandoned problematic threads that raised exception nobody
cared about.

Signed-off-by: Vratislav Podzimek <vpodzime at redhat.com>
---
 pyanaconda/threads.py | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/pyanaconda/threads.py b/pyanaconda/threads.py
index 29290df..0e81ded 100644
--- a/pyanaconda/threads.py
+++ b/pyanaconda/threads.py
@@ -121,6 +121,11 @@ class ThreadManager(object):
             log.debug("Waiting for thread %s to exit", name)
             self.wait(name)
 
+        if self.any_errors:
+            msg = "Unhandled errors from the following threads detected: %s" %\
+                         ", ".join(self._errors.iterkeys())
+            raise RuntimeError(msg)
+
     def set_error(self, name, *exc_info):
         """Set the error data for a thread
 
@@ -199,6 +204,11 @@ class AnacondaThread(threading.Thread):
             self._prefix_thread_counts[prefix] = thread_num
             kwargs["name"] = prefix + str(thread_num)
 
+        if "fatal" in kwargs:
+            self._fatal = kwargs.pop("fatal")
+        else:
+            self._fatal = True
+
         threading.Thread.__init__(self, *args, **kwargs)
         self.daemon = True
 
@@ -212,7 +222,8 @@ class AnacondaThread(threading.Thread):
         # pylint: disable-msg=W0702
         except:
             threadMgr.set_error(self.name, *sys.exc_info())
-            sys.excepthook(*sys.exc_info())
+            if self._fatal:
+                sys.excepthook(*sys.exc_info())
         finally:
             threadMgr.remove(self.name)
             log.info("Thread Done: %s (%s)", self.name, self.ident)
-- 
1.8.4.2



More information about the anaconda-patches mailing list