Reputation: 30430
The handler in my code fails in some cases which then causes the whole playbook run to crash and I would like to catch those failures in the handler and do some sort of clean up.
Here's my playbook where I would ideally like the Rescue when handler fails
task to run:
- hosts: localhost
tasks:
- name: something something
block:
- name: Print a message
debug: msg='I execute normally'
changed_when: yes
notify: failing handler
rescue:
- name: Rescue when handler fails
debug:
msg: 'Rescue'
handlers:
- name: failing handler
command: /bin/false
How can I catch the failure from this failing handler
and run some tasks for cleanup?
Upvotes: 2
Views: 1483
Reputation: 7340
By default handlers run at the end of the section (pre_tasks
, tasks
, etc.) from where they are notified. However it is possible to trigger the handler immediately after a task by using a meta action, i.e. - meta: flush_handlers
.
Using this technique, we can trigger the handler immediately after the Print a message
task. Then the playbook can continue with the next task(s).
For example:
tasks:
- name: Print a message
debug:
msg: i execute normally
changed_when: true
notify: failing handler
- meta: flush_handlers
- name: rescue when handler fails
debug:
msg: rescue
when: _handler_status | default({}) is failed
handlers:
- name: failing handler
command: /bin/false
register: _handler_status
ignore_errors: true
As rightly pointed out by @Zeitounator, flushing handlers is fine for the above example where there is only 1 notifying task. However it may be undesirable when there are chances of other tasks notifying other handlers. In such case, the task can go under post_tasks
section. Like below:
tasks:
- name: Print a message
debug:
msg: i execute normally
changed_when: true
notify: failing handler
post_tasks:
- name: rescue when failing handler fails
debug:
msg: rescue
when: _handler_status | default({}) is failed
handlers:
- name: failing handler
command: /bin/false
register: _handler_status
ignore_errors: true
Upvotes: 2
Reputation: 44645
For the record, the above can't work as the time when your handler is notified and the time it will effectively run are totally distinct. You need to catch the failure when the handler runs, not when it is notified.
I would go that way.
Put your handler tasks in a file my_failing_handler.yaml
- block:
- name: the task that might fail
command: /bin/false
rescue:
- name: rescue when handler fails
debug:
msg: "rescue"
Then in your main playbook:
- hosts: localhost
tasks:
- name: Print a message
debug: msg='I execute normally'
changed_when: yes
notify: failing handler
handlers:
- name: failing handler
include_tasks: my_failing_handler.yaml
Upvotes: 3