Combine multiple exceptions into a linked one
When multiple tasks running at the same time throw exceptions previously we would not be able to rethrow all the combined ones which was suboptimal. Instead of doing that create a combined linked exception that can retain all of the exceptions that were thrown and rethrow that in the situation where more than one task fails. Change-Id: I8f882e0d58caa189d6bff2e33b0bc30c4cee553d
This commit is contained in:
committed by
Joshua Harlow
parent
ab9ca13055
commit
b0fa3b2c9a
@@ -16,6 +16,10 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import StringIO
|
||||
|
||||
import traceback
|
||||
|
||||
|
||||
class TaskFlowException(Exception):
|
||||
"""Base class for exceptions emitted from this library."""
|
||||
@@ -27,6 +31,33 @@ class Duplicate(TaskFlowException):
|
||||
pass
|
||||
|
||||
|
||||
class LinkedException(TaskFlowException):
|
||||
"""A linked chain of many exceptions."""
|
||||
def __init__(self, message, cause, tb):
|
||||
super(LinkedException, self).__init__(message)
|
||||
self.cause = cause
|
||||
self.tb = tb
|
||||
self.next = None
|
||||
|
||||
@classmethod
|
||||
def link(cls, exc_infos):
|
||||
first = None
|
||||
previous = None
|
||||
for exc_info in exc_infos:
|
||||
if not all(exc_info) or not len(exc_infos) == 3:
|
||||
raise ValueError("Invalid exc_info")
|
||||
buf = StringIO.StringIO()
|
||||
traceback.print_exception(exc_info[0], exc_info[1], exc_info[2],
|
||||
file=buf)
|
||||
exc = cls(str(exc_info[1]), exc_info[1], buf.getvalue())
|
||||
if previous is not None:
|
||||
previous.next = exc
|
||||
else:
|
||||
first = exc
|
||||
previous = exc
|
||||
return first
|
||||
|
||||
|
||||
class StorageError(TaskFlowException):
|
||||
"""Raised when logbook can not be read/saved/deleted."""
|
||||
|
||||
|
||||
@@ -349,10 +349,11 @@ class Flow(flow.Flow):
|
||||
except exc.InvalidStateException:
|
||||
pass
|
||||
finally:
|
||||
# TODO(harlowja): re-raise a combined exception when
|
||||
# there are more than one failures??
|
||||
for f in failures:
|
||||
if all(f.exc_info):
|
||||
if len(failures) > 1:
|
||||
exc_infos = [f.exc_info for f in failures]
|
||||
raise exc.LinkedException.link(exc_infos)
|
||||
else:
|
||||
f = failures[0]
|
||||
raise f.exc_info[0], f.exc_info[1], f.exc_info[2]
|
||||
|
||||
def handle_results():
|
||||
|
||||
Reference in New Issue
Block a user