Hyperlinkv0.8.0-beta.28

Effect

Effect.retryOrElseconsteffect/Effect.ts:4119
<A1, E, E1, R1, A2, E2, R2>(
  policy: Schedule<A1, NoInfer<E>, E1, R1>,
  orElse: (e: NoInfer<E>, out: A1) => Effect<A2, E2, R2>
): <A, R>(self: Effect<A, E, R>) => Effect<A | A2, E1 | E2, R | R1 | R2>
<A, E, R, A1, E1, R1, A2, E2, R2>(
  self: Effect<A, E, R>,
  policy: Schedule<A1, NoInfer<E>, E1, R1>,
  orElse: (e: NoInfer<E>, out: A1) => Effect<A2, E2, R2>
): Effect<A | A2, E1 | E2, R | R1 | R2>

Retries a failing effect and runs a fallback effect if retries are exhausted.

When to use

Use when you want to handle failures gracefully by specifying an alternative action after repeated failures.

Details

The Effect.retryOrElse function attempts to retry a failing effect multiple times according to a defined Schedule policy.

If the retries are exhausted and the effect still fails, it runs a fallback effect instead.

Example (Falling back after retries are exhausted)

import { Console, Data, Effect, Schedule } from "effect"

class NetworkTimeoutError extends Data.TaggedError("NetworkTimeoutError")<{}> {}

let attempt = 0
const networkRequest = Effect.gen(function*() {
  attempt++
  yield* Console.log(`Network attempt ${attempt}`)
  if (attempt < 3) {
    return yield* Effect.fail(new NetworkTimeoutError())
  }
  return "Network data"
})

// Retry up to 2 times, then fall back to cached data
const program = Effect.retryOrElse(
  networkRequest,
  Schedule.recurs(2),
  (error, retryCount) =>
    Effect.gen(function*() {
      yield* Console.log(`All ${retryCount} retries failed, using cache`)
      return "Cached data"
    })
)

Effect.runPromise(program).then(console.log)
// Output:
// Network attempt 1
// Network attempt 2
// Network attempt 3
// Network data
error handlingScheduleretry
Source effect/Effect.ts:411911 lines
export const retryOrElse: {
  <A1, E, E1, R1, A2, E2, R2>(
    policy: Schedule<A1, NoInfer<E>, E1, R1>,
    orElse: (e: NoInfer<E>, out: A1) => Effect<A2, E2, R2>
  ): <A, R>(self: Effect<A, E, R>) => Effect<A | A2, E1 | E2, R | R1 | R2>
  <A, E, R, A1, E1, R1, A2, E2, R2>(
    self: Effect<A, E, R>,
    policy: Schedule<A1, NoInfer<E>, E1, R1>,
    orElse: (e: NoInfer<E>, out: A1) => Effect<A2, E2, R2>
  ): Effect<A | A2, E1 | E2, R | R1 | R2>
} = internalSchedule.retryOrElse