관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - Swift] RxSwift의 에러 처리 시 주의사항 (do(onError:), single, catch) 본문

iOS 응용 (swift)

[iOS - Swift] RxSwift의 에러 처리 시 주의사항 (do(onError:), single, catch)

jake-kim 2022. 11. 22. 23:14

do(onError:)는 모든 스트림 에러 모두 처리

  • 상위 flatMap에서 에러 발생 시 1onError, 2onError 둘 다 동작
    • 1onError만 출력되지 않고 2onError도 출력된다는것을 주의
    • 중간에 flatMap으로 Observable<Void>로 변경하는데도, 상위 Observable<Bool>에서 발생한 error가 그대로 내려오므로 주의
struct MyError: Error {}

Observable<Void>
  .just(())
  .flatMap { _ -> Observable<Bool> in
    throw MyError()
  }
  .debug("1디버그")
  .do(
    onNext: {print("1next")},
    onError: {_ in print("1onError")},
    onCompleted: {print("1onCompleted")},
    onDispose: {print("1onDispose")}
  )
  .flatMap { _ -> Observable<Void> in
    .just(())
  }
  .debug("2디버그")
  .do(
    onNext: {print("2next")},
    onError: {_ in print("2onError")},
    onCompleted: {print("2onCompleted")},
    onDispose: {print("2onDispose")}
  )
  .subscribe()
  .disposed(by: self.disposeBag)

2디버그 -> subscribed
1디버그 -> subscribed
1디버그 -> Event error(MyError())
1onError
2디버그 -> Event error(MyError())
2onError
Unhandled error happened: MyError()
2디버그 -> isDisposed
1디버그 -> isDisposed
1onDispose
2onDispose

single과 asObservable

  • single은 success, error, dispose 이벤트만 발생하는데, 만약 single 스트림을 asObservable하면?
  • observable이벤트에서 성공 후 완료 시 complete 이벤트가 발생하는데, single 스트림을 asObservable 할 경우 이 이벤트만 없어진다고 생각
  • Single로 시작하고 asObservable로 변경했을때 error가 발생하면?
    • Observable이벤트와 동일하게 error, dispose 순서대로 방출
Single<Void>
  .just(())
  .flatMap { _ -> Single<Bool> in
    throw MyError()
  }
  .map { _ in () }
  .do(
    onSuccess: {print("next")},
    onError: {_ in print("onError")},
    onDispose: {print("onDispose")}
  )
  .asObservable()
    .debug("디버그")
    .do(
      onNext: {print("1next")},
      onError: {_ in print("1onError")},
      onCompleted: {print("1onCompleted")},
      onDispose: {print("1onDispose")}
    )
    .subscribe()
    .disposed(by: self.disposeBag)
    
디버그 -> subscribed
onError
디버그 -> Event error(MyError())
1onError
Unhandled error happened: MyError()
디버그 -> isDisposed
onDispose
1onDispose

catch의 의미

  • onError가 아닌 onNext로 변경하여 방출이 가능
  • catch에서 특정 처리하고싶은 에러 유형이면 처리 후 스트림에 just()를 방출하여, do에서 결국 next가 프린트
Single<Void>
  .just(())
  .debug("디버그")
  .flatMap { _ -> Single<Bool> in
    throw MyError()
  }
  .map { _ in () }
  .catch({ error in
    guard let error = error as? MyError else { throw error }
    print("handle error:", error)
    return Single<Void>.just(())
  })
    .do(
      onSuccess: {print("next")},
      onError: {_ in print("onError")},
      onDispose: {print("onDispose")}
    )
      .subscribe()
      .disposed(by: disposeBag)

디버그 -> subscribed
디버그 -> Event next(())
handle error: MyError()
next
디버그 -> Event completed
디버그 -> isDisposed
onDispose

 

Comments