네트워크 요청이 실패했을 때 바로 사용자에게 실패문구를 띄우는 것보다 2번더 요청해보고 사용자에게 실패문구를 띄우게 할 수 있다. 바로 retry() 연산자를 통해서이다. retry(2) 를 통해 첫번째 시도 + 2번 더요청 했음에도 실패한다면 catch() 연산자를 통해 실패 이벤트를 잡아낸다.
enum SampleError: Error {
case somethingWentWrong
}
func fetchData() -> AnyPublisher<String, SampleError> {
let shouldFail = Bool.random()
if shouldFail {
print("Fetching data failed, will retry...")
return Fail(error: SampleError.somethingWentWrong)
.eraseToAnyPublisher()
} else {
return Just("Data loaded successfully")
.setFailureType(to: SampleError.self)
.eraseToAnyPublisher()
}
}
var retryCount = 0
var cancellable = fetchData()
.handleEvents(receiveSubscription: { _ in
// 초기 시도를 카운트하지 않고, 재시도 시작 시에만 카운트
if retryCount > 0 { print("Retry attempt #\(retryCount)") }
retryCount += 1})
.retry(3) // 최대 3번 재시도
.sink(receiveCompletion: { completion in
switch completion {
case .finished:
print("Completed successfully")
case .failure(let error):
print("Failed after \(retryCount - 1) retries with error: \(error)")
}
}, receiveValue: { value in
print("Received value: \(value)")
})
먼저 retry연산자를 살펴보자. retry에서 주의할 점은 retry(3) 을 하면 3번 시도하는 것이 아니라 총 4번 시도한다! 첫번째 시도에서 실패하면 3번더 시도한다는 의미이기 때문이다.
enum SampleError2: Error {
case somethingWentWrong
}
func fetchData2() -> AnyPublisher<String, SampleError2> {
let shouldFail = Bool.random()
if shouldFail {
return Fail(error: SampleError2.somethingWentWrong)
.eraseToAnyPublisher()
} else {
return Just("Data loaded successfully")
.setFailureType(to: SampleError2.self)
.eraseToAnyPublisher()
}
}
var cancellable2 = fetchData2()
.catch { error -> Just<String> in
print("An error occurred: \(error)")
return Just("Handling error gracefully, returning fallback data.")
}
.sink(receiveCompletion: { completion in
switch completion {
case .finished:
print("Completed successfully or handled error gracefully.")
case .failure:
print("Should not see this because errors are handled.")
}
}, receiveValue: { value in
print("Received value: \(value)")
})
catch() 연산자는 단어 그대로 다운스트림 가기전 소비자쪽에서 에러를 잡아내어 또다른 스트림을 열거나 기타 처리를 해줄 수 있는 연산자이다.
https://www.kodeco.com/21773708-intermediate-combine/lessons/5
'Flutter' 카테고리의 다른 글
VSCode가 플러터 프로젝트 인식을 못하는 문제 (0) | 2024.05.19 |
---|---|
플러터 프로젝트 실행시 아이폰 실기기(or 시뮬)가 돌아가지 않는 문제 (0) | 2024.05.19 |
| Combine | 11. Mapping Errors (0) | 2024.05.14 |
| Combine | 10. Managing Backpressure (0) | 2024.05.14 |
| Combine | 9. Networking with Combine (0) | 2024.05.14 |