Merge "Combine multiple exceptions into a linked one"
This commit is contained in:
@@ -16,6 +16,10 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import StringIO
|
||||||
|
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
|
||||||
class TaskFlowException(Exception):
|
class TaskFlowException(Exception):
|
||||||
"""Base class for exceptions emitted from this library."""
|
"""Base class for exceptions emitted from this library."""
|
||||||
@@ -27,6 +31,33 @@ class Duplicate(TaskFlowException):
|
|||||||
pass
|
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):
|
class StorageError(TaskFlowException):
|
||||||
"""Raised when logbook can not be read/saved/deleted."""
|
"""Raised when logbook can not be read/saved/deleted."""
|
||||||
|
|
||||||
|
|||||||
@@ -350,10 +350,11 @@ class Flow(flow.Flow):
|
|||||||
except exc.InvalidStateException:
|
except exc.InvalidStateException:
|
||||||
pass
|
pass
|
||||||
finally:
|
finally:
|
||||||
# TODO(harlowja): re-raise a combined exception when
|
if len(failures) > 1:
|
||||||
# there are more than one failures??
|
exc_infos = [f.exc_info for f in failures]
|
||||||
for f in failures:
|
raise exc.LinkedException.link(exc_infos)
|
||||||
if all(f.exc_info):
|
else:
|
||||||
|
f = failures[0]
|
||||||
raise f.exc_info[0], f.exc_info[1], f.exc_info[2]
|
raise f.exc_info[0], f.exc_info[1], f.exc_info[2]
|
||||||
|
|
||||||
def handle_results():
|
def handle_results():
|
||||||
|
|||||||
Reference in New Issue
Block a user