Error Handling & Retry Patterns
Robot Framework 5 introduced native TRY / EXCEPT / FINALLY / ELSE blocks inside keywords and tests. Together with built-in wrappers and Wait Until Keyword Succeeds, you can express recovery without scattering one-off workarounds.
TRY / EXCEPT (RF 5+)
Handle a failure, then continue with a fallback path:
*** Keywords ***
Click With Recovery
[Arguments] ${locator}
TRY
Click Element ${locator}
EXCEPT
Log Element not found, retrying... WARN
Wait Until Element Is Visible ${locator} timeout=10s
Click Element ${locator}
END
Narrow EXCEPT with message types or patterns when you want different handling for AssertionError vs timeout failures (see the User Guide for EXCEPT variants).
Run Keyword And Ignore Error / Run Keyword And Expect Error
| Keyword | Behavior |
|---|---|
Run Keyword And Ignore Error |
Runs keyword; returns status + return value or error; does not fail the test. |
Run Keyword And Expect Error |
Fails the test unless the expected error message matches. |
Use Ignore Error for optional cleanup (close dialog if present). Use Expect Error for negative tests and contract checks.
Wait Until Keyword Succeeds
Retries a keyword until it passes or timeout elapses:
| Argument | Role |
|---|---|
timeout |
Maximum wall time (e.g. 30 s). |
retry_interval |
Pause between attempts (e.g. 500 ms). |
name |
Keyword to run. |
*args |
Arguments passed to that keyword. |
Retry API call (pseudo-keyword names):
Wait Until Keyword Succeeds 20s 1s GET And Expect 200 /health
Retry UI action:
Wait Until Keyword Succeeds 15s 500ms Click Element ${SUBMIT}
Prefer explicit timeouts on the inner keyword where possible so failures stay diagnosable.
Retry patterns (when to use what)
| Pattern | Use case |
|---|---|
Wait Until Keyword Succeeds |
Flaky I/O, eventual consistency, animations, load balancers. |
TRY / EXCEPT |
Alternate flows, logging context, controlled recovery. |
Run Keyword And Ignore Error |
Best-effort teardown steps, optional UI paths. |
Run Keyword If |
Branch on flags or previous assignment without failing. |
Fail fast: stop on critical failures
| Mechanism | Use |
|---|---|
Fatal Error |
Stops entire execution immediately (use sparingly—for unrecoverable environment faults). |
[Tags] robot:exit-on-failure |
Fail-fast behavior for tagged tests/suites per Robot’s reserved tags. |
Reserve fail-fast for smoke gates where continuing would corrupt data or waste cluster time.
Custom retry in a Python library
Keep Robot syntax thin; implement bounded retries in Python with logging:
import logging
import time
from typing import Callable, TypeVar
logger = logging.getLogger(__name__)
T = TypeVar("T")
def retry_call(
fn: Callable[[], T],
*,
attempts: int = 5,
delay_s: float = 0.5,
label: str = "operation",
) -> T:
last_exc: Exception | None = None
for i in range(1, attempts + 1):
try:
logger.debug("retry_call attempt=%s/%s label=%s", i, attempts, label)
return fn()
except Exception as exc: # noqa: BLE001 — boundary for automation retry
last_exc = exc
logger.warning("retry_call failed attempt=%s label=%s err=%s", i, label, exc)
time.sleep(delay_s)
assert last_exc is not None
raise last_exc
Expose a thin keyword Call With Retry that wraps API clients or file operations.
Logging on failures
- Use
Log ${message} level=WARNinsideEXCEPTwith locator, URL, user id (non-PII), and attempt count. - Capture screenshots or traces in teardown when a test fails (
Run Keyword If Test Failed+ library keywords). - Keep retry logs at DEBUG in CI when diagnosing flakiness without flooding default reports.