From 0656d1466ad4cc9161b7a390f8b4b8fc8fa7a34b Mon Sep 17 00:00:00 2001 From: James Cammarata Date: Mon, 28 Mar 2016 09:02:23 -0400 Subject: [PATCH] Adds two variables to facts when a task fails and a rescue block starts `ansible_failed_task`: Contains the task data, essentially a serialized view of the Task() object. `ansible_failed_result`: Contains the result of the task failure, which is identical in function to registering the result. Doing so automatically like this saves the user from having to register every result in a block and then trying to figure out which result had the failure Similar to the way try/except/finally work, these variables will not be available in the `always` portion of a block unless there is a corresponding `rescue` first. Fixes #12341 --- lib/ansible/plugins/strategy/__init__.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/ansible/plugins/strategy/__init__.py b/lib/ansible/plugins/strategy/__init__.py index f9a7d8ec0fa..2c24e802baa 100644 --- a/lib/ansible/plugins/strategy/__init__.py +++ b/lib/ansible/plugins/strategy/__init__.py @@ -216,6 +216,20 @@ class StrategyBase: if iterator.is_failed(host): self._tqm._failed_hosts[host.name] = True self._tqm._stats.increment('failures', host.name) + else: + # otherwise, we grab the current state and if we're iterating on + # the rescue portion of a block then we save the failed task in a + # special var for use within the rescue/always + state, _ = iterator.get_next_task_for_host(host, peek=True) + if state.run_state == iterator.ITERATING_RESCUE: + original_task = iterator.get_original_task(host, task) + self._variable_manager.set_nonpersistent_facts( + host, + dict( + ansible_failed_task=original_task.serialize(), + ansible_failed_result=task_result._result, + ), + ) else: self._tqm._stats.increment('ok', host.name) self._tqm.send_callback('v2_runner_on_failed', task_result, ignore_errors=task.ignore_errors)