Section 9/161 menit

9. Error Handling di Async Pipeline

9. Error Handling di Async Pipeline

Throwing AsyncSequence

Operator bisa dipakai pada sequence yang throwing maupun non-throwing. Jika input throwing, output juga throwing.

swift
// Pipeline dengan throwing sequence
let fetchedData: some AsyncSequence<Data, Error> = networkStream()

do {
    for await data in fetchedData
        .compacted()
        .removeDuplicates()
        .map { try parseJSON($0) } {
        display(data)
    }
} catch {
    showError(error)
}

Menangani Error Partial

Untuk error yang tidak harus mengakhiri seluruh pipeline, tangkap di dalam loop:

swift
// Tangkap error per-elemen tanpa menghentikan pipeline
let urls = urlStream()

for await url in urls {
    do {
        let data = try await fetchData(from: url)
        process(data)
    } catch {
        // Error di satu URL tidak menghentikan pemrosesan URL lain
        logError(error, for: url)
        continue
    }
}

Retry dengan Async Algorithms

Belum ada operator retry built-in, tapi bisa diimplementasikan dengan AsyncChannel:

swift
// Retry pattern dengan AsyncChannel
func withRetry<T>(
    maxAttempts: Int,
    operation: @escaping () async throws -> T
) async throws -> T {
    var lastError: Error?
    for attempt in 1...maxAttempts {
        do {
            return try await operation()
        } catch {
            lastError = error
            if attempt < maxAttempts {
                try await Task.sleep(for: .seconds(Double(attempt) * 0.5))
            }
        }
    }
    throw lastError!
}