<@ULVA73B9P> please try again here &gt; explain ...
# marvin-ai
n
@Marvin please try again here
explain raise_on_failure behaviour pls. Particularly, I want to clarify if this can be called directly to the task call (using just task_name(raise_on_failure=False) ), or only for task_name.submit().result(raise_on_failure=False)? What is the default value and what are typical cases in Prefect v3? I want to make the task fail (red in UI) but proceed with the next task. When I just raise the exception in my task, the whole flow fails
(i'll look into what happened)
πŸ™Œ 1
m
βœ… thought for 118.2 seconds
Yep β€” the key distinction is where
raise_on_failure
lives. Short answer -
task_name(raise_on_failure=False)
β†’ no, that is not how Prefect v3 task calls work -
task_name.submit(...).result(raise_on_failure=False)
β†’ yes -
state.result(raise_on_failure=False)
β†’ yes - Default is
raise_on_failure=True
So if you call a task normally and it raises, Prefect will usually propagate that exception into the flow, which causes the flow to fail too. To make a task show as failed in the UI but allow the flow to continue, the usual pattern is:
Copy code
python
state = task_name(..., return_state=True)

if state.is_failed():
    err = state.result(raise_on_failure=False)
    # log / branch / ignore / handle
That task run will still be red in the UI, but since you captured the
State
instead of letting the exception bubble, the flow can keep going. Example
Copy code
python
from prefect import flow, task

@task
def step_1():
    raise ValueError("boom")

@task
def step_2():
    print("still running")

@flow
def my_flow():
    state = step_1(return_state=True)

    if state.is_failed():
        err = state.result(raise_on_failure=False)
        print(f"step_1 failed: {err}")

    step_2()

my_flow()
What happens here: -
step_1
is marked Failed in Prefect -
step_2
still runs - the flow can still complete successfully unless you re-raise or otherwise fail it yourself Why your flow currently fails When you do this:
Copy code
python
result = step_1()
and
step_1
raises, Prefect resolves the task result with the default behavior of
raise_on_failure=True
, so the exception is re-raised into the flow. Typical cases for
raise_on_failure=False
Usually used when you want to: - inspect a failed task without crashing the flow - implement best-effort / optional tasks - branch on success vs failure - collect partial results from many submitted tasks Examples:
Copy code
python
future = my_task.submit()
value_or_exc = future.result(raise_on_failure=False)
or
Copy code
python
state = my_task(return_state=True)
value_or_exc = state.result(raise_on_failure=False)
Important nuance If you want the task to fail and downstream tasks to continue, you usually need state-based control flow, not ordinary Python result passing. Because this will still blow up:
Copy code
python
x = my_task()   # failing task -> exception raised into flow
next_task()
Whereas this will not:
Copy code
python
state = my_task(return_state=True)
next_task()
Rule of thumb - Want the actual result and fail fast? β†’
my_task()
- Want to inspect success/failure yourself? β†’
my_task(return_state=True)
- Want concurrent execution? β†’
future = my_task.submit()
, then
future.result(...)
Relevant docs/source-backed behavior: - Prefect tasks - Prefect flows - Prefect state reference If you want, I can also show: 1. the same pattern for
.submit()
futures, or 2. how to structure a flow so the flow ends in a custom state like β€œcompleted with some task failures.”