Failures and Retries
Commands fail: a network call times out, a server is down. This lesson retries a flaky step, lets an optional step fail without stopping the run, and runs cleanup at the end.
The workflow
bash
curl -fsSLO https://docs.dagu.sh/tutorial/dags/tutorial-06-failures-and-retries.yamlyaml
# Dagu tutorial, lesson 6: https://docs.dagu.sh/tutorial/failures-and-retries
description: Retry a flaky step, tolerate an optional failure, and clean up
type: graph
handler_on:
failure:
run: echo "Alert - the run failed"
exit:
run: echo "Cleanup - runs after every run"
steps:
- id: call_api
working_dir: ${context.paths.artifacts_dir}
run: |
if [ -f attempted ]; then
echo "API responded"
else
touch attempted
echo "API timed out" >&2
exit 1
fi
retry_policy:
limit: 2
interval_sec: 2
- id: warm_cache
run: |
echo "Cache server unreachable" >&2
exit 1
continue_on: failed
- id: publish
run: echo "Published the report"
timeout_sec: 30
depends: [call_api, warm_cache]retry_policyruns a failed step again, here up to 2 more times, 2 seconds apart.call_apifails the first time and succeeds on the retry.continue_on: failedlets the steps afterwarm_cacherun even though it fails. The run ends as Partially succeeded, so the failure is still recorded.timeout_secfailspublishif it runs longer than 30 seconds.handler_onruns extra commands when the run ends.failureruns only when the run fails.exitruns after every run.
Watch it run
Handlers
warm_cacherunFailed
Cache server unreachable
call_api shows retried 1×. The failure handler stays Not started, because the run did not fail.
Run it yourself
bash
dagu start tutorial-06-failures-and-retries.yamlThe command exits with an error, because the run is only partially successful.
Retry a failed run
A retry runs a failed run again under the same run ID, with the definition and parameters it started with. Retry once the cause of the failure is gone, such as a server that is back up.
- Change
limit: 2tolimit: 0incall_apiand start the workflow.call_apifails with no retries left,publishends as Aborted, and thefailurehandler runs. - Retry the run. In the Web UI, select the retry button in the workflow bar. In the terminal, copy the run ID from
dagu history:
bash
dagu history tutorial-06-failures-and-retries.yaml
dagu retry --run-id=<run-id> tutorial-06-failures-and-retries.yamlThis time call_api succeeds, as the simulated API has recovered, and the run ends as Partially succeeded.
Try it
- Remove
continue_on: failedfromwarm_cacheand run again. What happens topublish? - Change
publishtorun: sleep 5withtimeout_sec: 1. What happens?
Answers
publishends as Aborted without running, the run fails, and thefailurehandler runs.- Dagu stops
publishafter one second and marks it Failed with a timeout error.

