31 lines · 971 B · Swift
RawDownload
import Foundation enum ProviderCandidateRetryRunnerError: Error {    case noCandidates} enum ProviderCandidateRetryRunner {    static func run<Candidate, Output>(        _ candidates: [Candidate],        shouldRetry: (Error) -> Bool,        onRetry: (Candidate, Error) -> Void = { _, _ in },        attempt: (Candidate) async throws -> Output) async throws -> Output    {        guard !candidates.isEmpty else {            throw ProviderCandidateRetryRunnerError.noCandidates        }         for (index, candidate) in candidates.enumerated() {            do {                return try await attempt(candidate)            } catch {                let hasMoreCandidates = index + 1 < candidates.count                guard hasMoreCandidates, shouldRetry(error) else {                    throw error                }                onRetry(candidate, error)            }        }        throw ProviderCandidateRetryRunnerError.noCandidates    }}