[RxSwift] 에러 핸들링 : catch, retry

Lily·2022년 6월 26일
0

rxSwift🏃🏻‍♀️

목록 보기
5/6

기본적으로 옵저버블에서 error가 방출되면 해당 옵저버블을 구독하고 있는 스트림은 모두 종료됩니다. 따라서 더 이상 next 이벤트가 방출되지 않습니다.

그럼 error가 방출되었을 때 에러 핸들링을 어떻게 해줄 것인지,
error가 방출되어도 스트림을 종료시키지 않고 이벤트를 받을 수 있는 방법은 무엇이 있을지
알아보도록 하겠습니다!

go go


catch, catchAndReturn

error가 방출되면 다른 아이템으로 옵저버블 시퀀스를 생성해 onError대신 onNext를 방출하고 completed 됩니다. error대신 다른 item을 내보내고 종료시키는 방법입니다.

catch(_ handler: )

handler에서 다른 itemonNext로 내보내는 새로운 옵저버블을 생성해서 리턴합니다.

output.products
            .catch({ _ in
                return Observable.just([]) // 에러 발생시 [] 전달
            })
            .observe(on: MainScheduler.instance)
            .bind(to: tableView.rx.items(cellIdentifier: "ProductTableViewCell", cellType: ProductTableViewCell.self)) { (row, element, cell) in
                cell.fill(with: element)}
            .disposed(by: disposeBag)

catchAndRetunrn(_ element: )

error 대신 내보낼 itemelement 넣어줍니다.

output.products
            .catchAndReturn([]) // 에러 발생시 빈배열 전달
            .observe(on: MainScheduler.instance)
            .bind(to: tableView.rx.items(cellIdentifier: "ProductTableViewCell", cellType: ProductTableViewCell.self)) { (row, element, cell) in
                cell.fill(with: element)}
            .disposed(by: disposeBag)

retry, retry(_ maxAttemptCount:), retry(when:)


옵저버블에서 error가 방출되었을 때, 옵저버블을 구독하고 있는 시퀀스를 dispose시키고 다시 subscribe을 합니다. 이때 error는 옵저버에게 전달되지 않습니다. (따라서 onNext만 옵저버에게 전달되는 것이 보장됩니다)

retry()를 사용했을 때 옵저버블의 상태변화를 debug() 로 찍어서 확인해봤습니다.

2022-06-20 17:07:40.715: JuiceMakerViewModel.swift:50 (transfrom(input:)) -> Event error(juiceProductionFailure)
2022-06-20 17:07:40.724: JuiceMakerViewModel.swift:50 (transfrom(input:)) -> isDisposed
2022-06-20 17:07:40.724: JuiceMakerViewModel.swift:50 (transfrom(input:)) -> subscribed

retry는 3가지 종류가 있습니다.
retryonNext를 받을 때까지 무제한 구독을,
retry(_ maxAttemptCount:)는 제한된 횟수만큼 구독을,
retry(when:)은 특정 이벤트가 발생할 때만 구독을 합니다.

retry

error가 방출되면, 스트림을 dispose하고 다시 subscribe합니다.
에러가 발생할 때마다, 성공적으로 종료(onComplete)될 때까지 무한정 재구독을 해주는 연산자입니다.

그래서 유의해서 사용해야합니다!! 특히 통신을 포함하는 스트림의 경우,error대신 올바른 response를 받을 때까지 계속 통신을 시도하므로 유의해서 사용해야합니다.

retry(_ maxAttemptCount:)

retry는 재구독을 하는 횟수에 제한이 없었다면, retry(maxAttemptCount:)는 정해진 횟수만큼 retry를 해줍니다.
maxAttemptCount에 제한 횟수를 넣어줍니다.
마지막 찬스에도 에러가 방출되면 옵저버에게 onError이벤트가 전달되고 스트림은 종료됩니다.

retry(when notificationHandler:)

어떠한 옵저버블에서 next가 방출될 때 다시 구독을 합니다.

예를 들어 특정한 버튼이 눌렸을 때만 구독을 시켜주고 싶다고 한다면 notificationHandler에 버튼이 탭되었을 때 onNext를 보내는 옵저버블을 넣어주면 됩니다.

profile
i🍎S 개발을 합니다

0개의 댓글