API reference › @evolu/common › Task › retry
function retry<T, E, D, Output>(
task: Task<T, E, D>,
schedule: Schedule<Output, Exclude<E, AbortError>>,
__namedParameters?: RetryOptions<Exclude<E, AbortError>, Output>,
): Task<T, RetryTaskError<E>, D>;
Defined in: packages/common/src/Task.ts:3979
Retries a Task according to a Schedule.
Use retry for failure recovery: it repeats after Err and wraps the
final domain error. Use repeat for success-driven loops: it repeats
after Ok and returns the Task's natural Result.
AbortError passes through unchanged when returned as a Result error,
such as from daemon. Abort from run(task) remains Fiber
control flow. Other errors are domain errors: retrying continues while the
schedule yields another delay and RetryOptions.shouldRetry returns
true. When retrying stops, retry returns RetryError with the final
domain error as lastError.
AbortError recognition is structural. Domain errors, especially values parsed from untrusted input, must not use the reserved AbortError shape.
Retrying failures
import {
assertErr,
assertType,
createRun,
err,
recurs,
retry,
type Result,
type RetryTaskError,
type Task,
type Typed,
} from "@evolu/common";
const fetchData: Task<string, ServiceUnavailableError> = () =>
err({ type: "ServiceUnavailable" });
interface ServiceUnavailableError extends Typed<"ServiceUnavailable"> {}
const fetchWithRetry = retry(fetchData, recurs(2));
await using run = createRun();
const result = await run(fetchWithRetry);
assertType<
Result<string, RetryTaskError<ServiceUnavailableError>>,
typeof result
>();
assertErr(result, {
type: "RetryError",
attempts: 3,
lastError: { type: "ServiceUnavailable" },
});
Filtering retries
import {
assertErr,
createRun,
err,
recurs,
retry,
type Task,
type Typed,
} from "@evolu/common";
const fetchData: Task<
string,
TemporaryFailureError | PermanentFailureError
> = () => err({ type: "PermanentFailure" });
interface TemporaryFailureError extends Typed<"TemporaryFailure"> {}
interface PermanentFailureError extends Typed<"PermanentFailure"> {}
const fetchWithRetry = retry(fetchData, recurs(5), {
shouldRetry: (error) => error.type !== "PermanentFailure",
});
await using run = createRun();
const result = await run(fetchWithRetry);
assertErr(result, {
type: "RetryError",
attempts: 1,
lastError: { type: "PermanentFailure" },
});