BACK
Use casesConditional retry — retry only transient errors
Use cases · 31

Conditional retry — retry only transient errors

Pattern

A 500 or network error (status 0) is often a temporary glitch, worth retrying a second later. A 400 (bad request) or 401 (not authorized) is a broken payload or an expired token — pointless to retry.

The problem it solves

A plain retry(3) retries EVERYTHING, including 400s. We annoy the backend with needless load and mask real bugs in our own code. You need conditional logic: what to retry, what not, with what delay.

Operators and why they matter

  • retry({ count, delay }) — the delay callback receives the error and decides whether to retry it.
  • timer(retryIndex * 10) — backoff: the second attempt waits longer than the first.
  • throwError inside the delay callback — stops the retry for permanent errors. Return an error → the retry turns into a real fail.
  • catchError — turn the final failure (after all attempts) into a UI state.

Gotchas

  • retry with no limit (count) — an infinite loop if the error is permanent.
  • Without a condition you retry 400/401 — pointless and annoying to the backend.
  • Don't retry a non-idempotent mutation (a POST without an idempotency key) — two charges, two messages, two bookings.

What you get

A transient failure recovers transparently. A client error instantly becomes a clear failure without a series of useless retries.

script.ts // TypeScript
CONSOLE · Console output
Hit Run to see the result...