Add 'raise_with_cause' chaining helper to excutils
This code is currently shared by tooz and taskflow and it seems like a good candiate to be used and shared by others as well (and excutils seems like an obvious home for it). Change-Id: I7e7c094085d6d5b5e32ec40201e260f032d0fdef
This commit is contained in:
parent
466ecc30c4
commit
406d182f5a
@ -27,6 +27,40 @@ import six
|
|||||||
from oslo_utils._i18n import _LE
|
from oslo_utils._i18n import _LE
|
||||||
|
|
||||||
|
|
||||||
|
def raise_with_cause(exc_cls, message, *args, **kwargs):
|
||||||
|
"""Helper to raise + chain exceptions (when able) and associate a *cause*.
|
||||||
|
|
||||||
|
NOTE(harlowja): Since in py3.x exceptions can be chained (due to
|
||||||
|
:pep:`3134`) we should try to raise the desired exception with the given
|
||||||
|
*cause* (or extract a *cause* from the current stack if able) so that the
|
||||||
|
exception formats nicely in old and new versions of python. Since py2.x
|
||||||
|
does **not** support exception chaining (or formatting) the exception
|
||||||
|
class provided should take a ``cause`` keyword argument (which it may
|
||||||
|
discard if it wants) to its constructor which can then be
|
||||||
|
inspected/retained on py2.x to get *similar* information as would be
|
||||||
|
automatically included/obtainable in py3.x.
|
||||||
|
|
||||||
|
:param exc_cls: the exception class to raise.
|
||||||
|
:param message: the text/str message that will be passed to
|
||||||
|
the exceptions constructor as its first positional
|
||||||
|
argument.
|
||||||
|
:param args: any additional positional arguments to pass to the
|
||||||
|
exceptions constructor.
|
||||||
|
:param kwargs: any additional keyword arguments to pass to the
|
||||||
|
exceptions constructor.
|
||||||
|
"""
|
||||||
|
if 'cause' not in kwargs:
|
||||||
|
exc_type, exc, exc_tb = sys.exc_info()
|
||||||
|
try:
|
||||||
|
if exc is not None:
|
||||||
|
kwargs['cause'] = exc
|
||||||
|
finally:
|
||||||
|
# Leave no references around (especially with regards to
|
||||||
|
# tracebacks and any variables that it retains internally).
|
||||||
|
del(exc_type, exc, exc_tb)
|
||||||
|
six.raise_from(exc_cls(message, *args, **kwargs), kwargs.get('cause'))
|
||||||
|
|
||||||
|
|
||||||
class save_and_reraise_exception(object):
|
class save_and_reraise_exception(object):
|
||||||
"""Save current exception, run some code and then re-raise.
|
"""Save current exception, run some code and then re-raise.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user