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.

  • 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.

New in version 2.4.

pformat(indent=2, indent_text=' ', show_root_class=False)

Pretty formats a caused exception + any connected causes.

class oslo_utils.excutils.exception_filter(should_ignore_ex)

A context manager that prevents some exceptions from being raised.

Use this class as a decorator for a function that returns whether a given exception should be ignored, in cases where complex logic beyond subclass matching is required. e.g.

>>> @exception_filter
>>> def ignore_test_assertions(ex):
...     return isinstance(ex, AssertionError) and 'test' in str(ex)

The filter matching function can then be used as a context manager:

>>> with ignore_test_assertions:
...     assert False, 'This is a test'

or called directly:

>>> try:
...     assert False, 'This is a test'
... except Exception as ex:
...     ignore_test_assertions(ex)

Any non-matching exception will be re-raised. When the filter is used as a context manager, the traceback for re-raised exceptions is always preserved. When the filter is called as a function, the traceback is preserved provided that no other exceptions have been raised in the intervening time. The context manager method is preferred for this reason except in cases where the ignored exception affects control flow.

oslo_utils.excutils.forever_retry_uncaught_exceptions(*args, **kwargs)

Decorates provided function with infinite retry behavior.

The function retry delay is always one second unless keyword argument retry_delay is passed that defines a value different than 1.0 (less than zero values are automatically changed to be 0.0).

If repeated exceptions with the same message occur, logging will only output/get triggered for those equivalent messages every 60.0 seconds, this can be altered by keyword argument same_log_delay to be a value different than 60.0 seconds (exceptions that change the message are always logged no matter what this delay is set to). As in the retry_delay case if this is less than zero, it will be automatically changed to be 0.0.

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.

  • 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.

New in version 1.6.

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:
        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

Changed in version 1.4: Added logger optional parameter.