fun <T> Flow<T>.retryWhen(
    predicate: suspend FlowCollector<T>.(cause: Throwable, attempt: Long) -> Boolean
): Flow<T>

Retries collection of the given flow when an exception occurs in the upstream flow and the predicate returns true. The predicate also receives an attempt number as parameter, starting from zero on the initial call. This operator is transparent to exceptions that occur in downstream flow and does not retry on exceptions that are thrown to cancel the flow.

For example, the following call retries the flow forever if the error is caused by IOException, but stops after 3 retries on any other exception:

flow.retryWhen { cause, attempt -> cause is IOException || attempt < 3 }

To implement a simple retry logic with a limit on the number of retries use retry operator.

Similarly to catch operator, the predicate code has FlowCollector as a receiver and can emit values downstream. The predicate is a suspending function, so it can be used to introduce delay before retry, for example:

flow.retryWhen { cause, attempt ->
    if (cause is IOException) {    // retry on IOException
        delay(1000)                // delay for one second before retry
    } else {                       // do not retry otherwise

See catch for more details.

inline fun <T> SharedFlow<T>.retryWhen(
    noinline predicate: suspend FlowCollector<T>.(cause: Throwable, attempt: Long) -> Boolean
): Flow<T>

Deprecated: SharedFlow never completes, so this operator has no effect.