<@ULVA73B9P> I want a task to not stop the flow ex...
# ask-marvin
m
@Marvin I want a task to not stop the flow execution if it crashes, is there a prefect-way of doing this or should I handle the logic within the task with a standard try/except?
m
thought for 336.4 seconds
Great question. In Prefect 3.x there are a few “Prefect-native” ways to let a task fail without stopping the rest of your flow, so you don’t have to rely solely on try/except inside the task. Here are the recommended patterns and when to use them: - If you want downstream tasks to still run when an upstream task fails: use
allow_failure
- This tells Prefect to allow a failed upstream input and passes the exception into the downstream task as the value. - Example:
Copy code
from prefect import flow, task
    from prefect.utilities.annotations import allow_failure

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

    @task
    def handle(x):
        if isinstance(x, Exception):
            return "handled failure"
        return x

    @flow
    def my_flow():
        fut = risky()
        return handle(allow_failure(fut))
- Docs: allow_failure annotation - If you want to inspect a task’s outcome in the flow without raising: use
future.result(raise_on_failure=False)
- This returns the exception object instead of raising it so your flow can keep going.
Copy code
from prefect import flow, task

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

    @flow
    def my_flow():
        fut = risky()
        res = fut.result(raise_on_failure=False)
        if isinstance(res, Exception):
            # log or fallback
            return "recovered"
        return res
- Docs: prefect.futures and PrefectFuture.result - If the error is transient: use retries (optionally with backoff or conditions) - This doesn’t “hide” failures, but it reduces them.
Copy code
from prefect import task
    from prefect.tasks import exponential_backoff

    @task(retries=3, retry_delay_seconds=exponential_backoff(2))
    def sometimes_flaky():
        ...
- Docs: Retries guide - Try/except inside the task is okay, but be aware of trade-offs - If you swallow errors inside the task and return a fallback, Prefect will mark the task as COMPLETED. That can hide genuine failures from monitoring/alerting. - Prefer letting the task fail and handling it at the flow/dependency boundary with
allow_failure
or
result(raise_on_failure=False)
when you want observability of failures. A few behavioral notes: - By default, a failed upstream blocks dependent tasks (raising
UpstreamTaskError
).
allow_failure
bypasses that for specific dependencies. - Docs: UpstreamTaskError - The flow does not “stop” globally when a task fails; other independent branches continue. The flow will be marked failed if you resolve/return a failed future without handling it. If you want the flow to finish “successfully” despite certain task failures, handle those failures and avoid returning unresolved failed futures from the flow. If you can share your specific pattern (e.g., “task B depends on task A but should still run when A fails” vs. “I just don’t want the whole flow to fail if some tasks crash”), I can suggest the cleanest snippet for your case.