excutils

Exception related utilities.

exception oslo_utils.excutils.CausedByException(message, cause=None)

Base class for exceptions which have associated causes.

NOTE(harlowja): in later versions of python we can likely remove the need to have a cause here as PY3+ have implemented PEP 3134 which handles chaining in a much more elegant manner.

Parameters:
  • message – the exception message, typically some string that is useful for consumers to view when debugging or analyzing failures.
  • cause – the cause of the exception being raised, when provided this should itself be an exception instance, this is useful for creating a chain of exceptions for versions of python where this is not yet implemented/supported natively.
pformat(indent=2, indent_text=' ', show_root_class=False)

Pretty formats a caused exception + any connected causes.

oslo_utils.excutils.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.

Parameters:
  • exc_cls – the exception class to raise (typically one derived from CausedByException or equivalent).
  • message – the text/str message that will be passed to the exceptions constructor as its first positional argument.
  • args – any additional positional arguments to pass to the exceptions constructor.
  • kwargs – any additional keyword arguments to pass to the exceptions constructor.
class oslo_utils.excutils.save_and_reraise_exception(reraise=True, logger=None)

Save current exception, run some code and then re-raise.

In some cases the exception context can be cleared, resulting in None being attempted to be re-raised after an exception handler is run. This can happen when eventlet switches greenthreads or when running an exception handler, code raises and catches an exception. In both cases the exception context will be cleared.

To work around this, we save the exception state, run handler code, and then re-raise the original exception. If another exception occurs, the saved exception is logged and the new exception is re-raised.

In some cases the caller may not want to re-raise the exception, and for those circumstances this context provides a reraise flag that can be used to suppress the exception. For example:

except Exception:
    with save_and_reraise_exception() as ctxt:
        decide_if_need_reraise()
        if not should_be_reraised:
            ctxt.reraise = False

If another exception occurs and reraise flag is False, the saved exception will not be logged.

If the caller wants to raise new exception during exception handling he/she sets reraise to False initially with an ability to set it back to True if needed:

except Exception:
    with save_and_reraise_exception(reraise=False) as ctxt:
        [if statements to determine whether to raise a new exception]
        # Not raising a new exception, so reraise
        ctxt.reraise = True