diff --git a/changelogs/fragments/11488-mh-ensure-compatibiliy-with-module-tests.yml b/changelogs/fragments/11488-mh-ensure-compatibiliy-with-module-tests.yml new file mode 100644 index 0000000000..25312f77d5 --- /dev/null +++ b/changelogs/fragments/11488-mh-ensure-compatibiliy-with-module-tests.yml @@ -0,0 +1,2 @@ +minor_changes: + - ModuleHelper module utils - allow to ignore specific exceptions in ``module_fails_on_exception`` decorator (https://github.com/ansible-collections/community.general/pull/11488). diff --git a/plugins/module_utils/mh/deco.py b/plugins/module_utils/mh/deco.py index e05492b66a..207ccc38dd 100644 --- a/plugins/module_utils/mh/deco.py +++ b/plugins/module_utils/mh/deco.py @@ -6,9 +6,15 @@ from __future__ import annotations import traceback +from contextlib import contextmanager from functools import wraps -from ansible_collections.community.general.plugins.module_utils.mh.exceptions import ModuleHelperException +from ansible_collections.community.general.plugins.module_utils.mh.exceptions import ( + ModuleHelperException, + _UnhandledSentinel, +) + +_unhandled_exceptions: tuple[type[Exception], ...] = (_UnhandledSentinel,) def cause_changes(when=None): @@ -32,6 +38,17 @@ def cause_changes(when=None): return deco +@contextmanager +def no_handle_exceptions(*exceptions: type[Exception]): + global _unhandled_exceptions + current = _unhandled_exceptions + _unhandled_exceptions = tuple(exceptions) + try: + yield + finally: + _unhandled_exceptions = current + + def module_fails_on_exception(func): conflict_list = ("msg", "exception", "output", "vars", "changed") @@ -46,6 +63,9 @@ def module_fails_on_exception(func): try: func(self, *args, **kwargs) + except _unhandled_exceptions: + # re-raise exception without further processing + raise except ModuleHelperException as e: if e.update_output: self.update_output(e.update_output) diff --git a/plugins/module_utils/mh/exceptions.py b/plugins/module_utils/mh/exceptions.py index 612cfc1c3c..64c0d4b176 100644 --- a/plugins/module_utils/mh/exceptions.py +++ b/plugins/module_utils/mh/exceptions.py @@ -15,3 +15,7 @@ class ModuleHelperException(Exception): update_output = {} self.update_output: dict[str, t.Any] = update_output super().__init__(*args) + + +class _UnhandledSentinel(Exception): + pass