Index: recipe_engine/util.py |
diff --git a/recipe_engine/util.py b/recipe_engine/util.py |
index cb3257b37f1f98027aae40c9b4b699c15d88c26a..cf355cfab4787f04b1a5df9476ccb89dcd936e6e 100644 |
--- a/recipe_engine/util.py |
+++ b/recipe_engine/util.py |
@@ -190,3 +190,47 @@ class StringListIO(object): |
def close(self): |
if not isinstance(self.lines[-1], basestring): |
self.lines[-1] = self.lines[-1].getvalue() |
+ |
+ |
+class MultiException(Exception): |
+ """An exception that aggregates multiple exceptions and summarizes them.""" |
+ |
+ def __init__(self): |
+ self._inner = [] |
+ |
+ def append(self, exc): |
+ assert isinstance(exc, BaseException) |
+ self._inner.append(exc) |
+ |
+ def __nonzero__(self): |
+ return bool(self._inner) |
+ |
+ def __str__(self): |
+ if len(self._inner) == 0: |
+ text = 'No exceptions' |
+ elif len(self._inner) == 1: |
+ text = str(self._inner[0]) |
+ else: |
+ text = str(self._inner[0]) + ', and %d more...' % (len(self._inner)-1) |
+ return '%s(%s)' % (type(self).__name__, text) |
+ |
+ def raise_if_any(self): |
+ if self: |
martiniss
2016/09/01 21:59:48
Shouldn't this be "if self._inner"?
dnj
2016/09/07 17:54:58
Done.
|
+ raise self |
+ |
+ @contextlib.contextmanager |
+ def catch(self): |
+ try: |
+ yield |
+ except Exception as e: |
martiniss
2016/09/01 21:59:48
Can you make the exception class a required parame
dnj
2016/09/07 17:54:58
Sure.
However, note the only user ("defer_excepti
|
+ self.append(e) |
+ |
+ |
+def defer_exceptions_for(gen): |
+ mexc = MultiException() |
+ for e in gen: |
+ try: |
+ yield e |
+ except Exception as e: |
+ exc.append(e) |
+ mexc.raise_if_any() |