Ansible Error Handling Snippet
Hi team I was going through the error handling document here and doing some hands-on: https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_error_handling.html
I found a certain snippet related to the failed_when feature Defining failure section:
failed_when: result.rc == 0 or "No such" not in result.stdout
Now, the purpose of the task was to cause a failure if the file exists. Let's consider the 2 scenarios:
- File is NOT present -> technically task should pass as that is the requirement
If the file is not present, it throws an error, but the error message would be present in the
result.stderrand not inresult.stdout. Also, rc would not be 0.false or truewould result intrueand task would fail -> Contradiction - File is present -> technically task should NOT pass as that is the requirement
If the file is present, it will have some genuine response in the
result.stdout(not related to the string pattern 'No such') and rc would be 0.true & truewould result intrueand task would fail -> Okay
This task will always fail in both the above scenarios.
I believe the requirement can be met with the following condition:
failed_when: result.rc == 0 or "No such" not in result.stderr
Hence, replacing result.stdout with result.stderr should do the trick.
Thanks for your Ansible docs contribution! We talk about Ansible documentation on matrix at #docs:ansible.im and on libera IRC at #ansible-docs if you ever want to join us and chat about the docs! We meet there on Tuesdays (see the Ansible calendar) and welcome additions to our weekly agenda items - scroll down to find the upcoming agenda and add a comment to put something new on that agenda.
Moving issue to ansible/ansible-documentation. Thanks @darkhorse1998 for opening the issue.
Confirmed - this task:
- name: use stdout to fail if we find /tmp/bad-file.yml
ansible.builtin.command: ls /tmp/bad-file.yml
register: result
failed_when: result.rc == 0 or "No such" not in result.stdout
returns this output when the file does not exist:
TASK [use stdout to fail if we find /tmp/bad-file.yml] ***********************************************************************************
fatal: [sandbox-acozine]: FAILED! => {"changed": true, "cmd": ["ls", "/tmp/bad-file.yml"], "delta": "0:00:00.008095", "end": "2024-10-08 10:45:43.985277", "failed_when_result": true, "msg": "non-zero return code", "rc": 2, "start": "2024-10-08 10:45:43.977182", "stderr": "ls: cannot access '/tmp/bad-file.yml': No such file or directory", "stderr_lines": ["ls: cannot access '/tmp/bad-file.yml': No such file or directory"], "stdout": "", "stdout_lines": []}
Whereas with stderr it behaves as desired - this task:
- name: use stderr to fail if we find /tmp/bad-file.yml
ansible.builtin.command: ls /tmp/bad-file.yml
register: result
failed_when: result.rc == 0 or "No such" not in result.stderr
returns this output when the file does not exist:
TASK [use stderr to fail if we find /tmp/bad-file.yml] *********************************************************************
changed: [sandbox-acozine]
I'll open a PR. Thanks @darkhorse1998 !