diff --git a/lib/ansible/module_utils/_internal/_traceback.py b/lib/ansible/module_utils/_internal/_traceback.py index abc33f70902..473765eff74 100644 --- a/lib/ansible/module_utils/_internal/_traceback.py +++ b/lib/ansible/module_utils/_internal/_traceback.py @@ -30,7 +30,7 @@ def is_traceback_enabled(event: TracebackEvent) -> bool: return _is_traceback_enabled(event) -def maybe_capture_traceback(event: TracebackEvent) -> str | None: +def maybe_capture_traceback(msg: str, event: TracebackEvent) -> str | None: """ Optionally capture a traceback for the current call stack, formatted as a string, if the specified traceback event is enabled. Frames marked with the `_skip_stackwalk` local are omitted. @@ -46,6 +46,7 @@ def maybe_capture_traceback(event: TracebackEvent) -> str | None: # DTFIX-FUTURE: rewrite target-side tracebacks to point at controller-side paths? tb_lines.append('Traceback (most recent call last):\n') tb_lines.extend(traceback.format_stack(frame_info.frame)) + tb_lines.append(f'Message: {msg}\n') else: tb_lines.append('(frame not found)\n') # pragma: nocover diff --git a/lib/ansible/module_utils/basic.py b/lib/ansible/module_utils/basic.py index 2f4ab349818..2d9688d6a79 100644 --- a/lib/ansible/module_utils/basic.py +++ b/lib/ansible/module_utils/basic.py @@ -1534,7 +1534,7 @@ class AnsibleModule(object): exception=_messages.ErrorSummary( event=_messages.Event( msg=msg, - formatted_traceback=_traceback.maybe_capture_traceback(_traceback.TracebackEvent.ERROR), + formatted_traceback=_traceback.maybe_capture_traceback(msg, _traceback.TracebackEvent.ERROR), chain=_messages.EventChain( msg_reason=_errors.MSG_REASON_DIRECT_CAUSE, traceback_reason="The above exception was the direct cause of the following error:", @@ -1554,7 +1554,7 @@ class AnsibleModule(object): elif exception is _UNSET and (current_exception := t.cast(t.Optional[BaseException], sys.exc_info()[1])): formatted_traceback = _traceback.maybe_extract_traceback(current_exception, _traceback.TracebackEvent.ERROR) else: - formatted_traceback = _traceback.maybe_capture_traceback(_traceback.TracebackEvent.ERROR) + formatted_traceback = _traceback.maybe_capture_traceback(msg, _traceback.TracebackEvent.ERROR) if formatted_traceback: kwargs.update(exception=formatted_traceback) diff --git a/lib/ansible/module_utils/common/warnings.py b/lib/ansible/module_utils/common/warnings.py index ee403d5fba3..1352f9189c8 100644 --- a/lib/ansible/module_utils/common/warnings.py +++ b/lib/ansible/module_utils/common/warnings.py @@ -33,7 +33,7 @@ def warn( event=_messages.Event( msg=warning, help_text=help_text, - formatted_traceback=_traceback.maybe_capture_traceback(_traceback.TracebackEvent.WARNING), + formatted_traceback=_traceback.maybe_capture_traceback(warning, _traceback.TracebackEvent.WARNING), ), ) @@ -79,7 +79,7 @@ def deprecate( event=_messages.Event( msg=msg, help_text=help_text, - formatted_traceback=_traceback.maybe_capture_traceback(_traceback.TracebackEvent.DEPRECATED), + formatted_traceback=_traceback.maybe_capture_traceback(msg, _traceback.TracebackEvent.DEPRECATED), ), version=version, date=date, diff --git a/lib/ansible/module_utils/datatag.py b/lib/ansible/module_utils/datatag.py index c89ba1f5f91..e2bc9c1504a 100644 --- a/lib/ansible/module_utils/datatag.py +++ b/lib/ansible/module_utils/datatag.py @@ -38,7 +38,7 @@ def deprecate_value( date=date, version=version, deprecator=_deprecator.get_best_deprecator(deprecator=deprecator, collection_name=collection_name), - formatted_traceback=_traceback.maybe_capture_traceback(_traceback.TracebackEvent.DEPRECATED_VALUE), + formatted_traceback=_traceback.maybe_capture_traceback(msg, _traceback.TracebackEvent.DEPRECATED_VALUE), ) return deprecated.tag(value) diff --git a/lib/ansible/plugins/action/__init__.py b/lib/ansible/plugins/action/__init__.py index 28a0dcd5af5..6e01885bc7f 100644 --- a/lib/ansible/plugins/action/__init__.py +++ b/lib/ansible/plugins/action/__init__.py @@ -1468,7 +1468,7 @@ class ActionBase(ABC, _AnsiblePluginInfoMixin): event = _messages.Event( msg=msg, - formatted_traceback=_traceback.maybe_capture_traceback(_traceback.TracebackEvent.ERROR), + formatted_traceback=_traceback.maybe_capture_traceback(msg, _traceback.TracebackEvent.ERROR), events=tuple(error.event for error in errors) if errors else None, ) diff --git a/lib/ansible/utils/display.py b/lib/ansible/utils/display.py index cd369da7205..2cf7cdefba2 100644 --- a/lib/ansible/utils/display.py +++ b/lib/ansible/utils/display.py @@ -699,7 +699,7 @@ class Display(metaclass=Singleton): help_text=help_text, obj=obj, deprecator=_deprecator.get_best_deprecator(deprecator=deprecator, collection_name=collection_name), - formatted_traceback=_traceback.maybe_capture_traceback(_traceback.TracebackEvent.DEPRECATED), + formatted_traceback=_traceback.maybe_capture_traceback(msg, _traceback.TracebackEvent.DEPRECATED), ) def _deprecated_with_plugin_info( @@ -801,7 +801,7 @@ class Display(metaclass=Singleton): msg=msg, help_text=help_text, formatted_source_context=formatted_source_context, - formatted_traceback=_traceback.maybe_capture_traceback(_traceback.TracebackEvent.WARNING), + formatted_traceback=_traceback.maybe_capture_traceback(msg, _traceback.TracebackEvent.WARNING), ), ) @@ -886,7 +886,7 @@ class Display(metaclass=Singleton): if msg: event = _messages.Event( msg=msg, - formatted_traceback=_traceback.maybe_capture_traceback(_traceback.TracebackEvent.WARNING), + formatted_traceback=_traceback.maybe_capture_traceback(msg, _traceback.TracebackEvent.WARNING), chain=_messages.EventChain( msg_reason=_errors.MSG_REASON_DIRECT_CAUSE, traceback_reason="The above exception was the direct cause of the following warning:", @@ -918,7 +918,7 @@ class Display(metaclass=Singleton): else: event = _messages.Event( msg=msg, - formatted_traceback=_traceback.maybe_capture_traceback(_traceback.TracebackEvent.ERROR), + formatted_traceback=_traceback.maybe_capture_traceback(msg, _traceback.TracebackEvent.ERROR), ) error = _messages.ErrorSummary(