Tom Han
09/03/2025, 6:17 PMraise
an exception or does returning none also triggers a retry?Marvin
09/03/2025, 6:17 PMMarvin
09/03/2025, 6:34 PMretries > 0
.
- Simply returning None
is a normal success (Completed) and will not trigger a retry.
More detail for Prefect 3.x:
- Retries apply when a task run finishes Failed or Crashed and there are attempts left. Prefect schedules the next attempt (state will move through AwaitingRetry → Retrying).
- Common ways a task “fails”:
- Your task function raises an exception
- The task times out (timeout_seconds
) which results in a failure
- The run crashes (infrastructure/runtime error)
- Returning any value, including None
, is a Completed state and does not retry by itself. If you want to retry on “bad” values, raise an exception when you detect the condition.
About retry_condition_fn:
- Use retry_condition_fn
to control which errors should be retried.
- It’s called when your task raises an exception and is given the exception; return True to retry, False to stop retrying and mark the task Failed.
- Example:
from prefect import task, flow
import httpx
@task(
retries=5,
retry_delay_seconds=10,
retry_condition_fn=lambda exc: isinstance(exc, httpx.HTTPStatusError)
and exc.response.status_code in (429, 503),
)
def fetch_url(url: str) -> str:
r = httpx.get(url)
r.raise_for_status()
return r.text
@flow
def my_flow():
fetch_url("<https://example.com>")
If you want to retry when a task returns None
, raise explicitly:
@task(retries=3, retry_delay_seconds=5)
def compute() -> int:
value = maybe_returns_none()
if value is None:
raise ValueError("Got None, retrying")
return value
If you share what behavior you want to retry on, I can sketch the exact retry_condition_fn
or task code for it.