본문 바로가기
iOS

[iOS/Swift] catchError로 error 처리하기

by 코코종 2022. 6. 26.

안녕하세요 코코종입니다.

오늘은 이전에 작성했던 [iOS/Swift] RxMoya(Moya) ErrorHandling 해보기(feat. Repository Pattern) 에서 nnError로 처리했던 부분에 대한 추가적인 내용을 가져왔습니다. (가져오고 싶지 않았는데 버그가..)

 

일단 제가 겪던 문제는 1. Error가 발생했을 때의 response에서 특정한 Model을 가져와서 사용한다. 2. onError에서 에러처리를 했기 때문에 한 번 Error가 발생하면 flatmap으로 연결되어 있는 옵저버블이 dispose 되어버린다.(에러는 확인이 가능하다) 3. 그러나 계속 subscribe를 해줘야 하는 상황...(에러가 또 발생하면 같은 동작을 하도록)


그래서 이에 대해 어떻게 처리할까 하면서 구글링을 했을 때 catchError를 사용하면 되겠다고 생각하고 적용했습니다.

공식문서를 간단한게 요약하자면 '에러가 발생해도 do try catch문 처럼 에러가 발생시에 onError가 되지 않고 특정한 값을 리턴해서 onCompleted 되게한다'

input.deletePet
          .observeOn(backgroundScheduler)
          .flatMap{ (myPet: MyPet) -> Observable<Bool> in
            let deleteMyPet = self.myPetsRepo.deleteMyPet(petId: String(myPet.id))
            return deleteMyPet
          }
          .catchError({ error in
            guard let moyaError = error as? MoyaError else { return Observable.empty() }
            let data = moyaError.response?.data
            
            do {
              let json = try JSONSerialization.jsonObject(with: data!) as! errorModel
              print(json.errorCode)
              print(json.errorMessage)
            }
            catch {
              print("json parsing error")
            }
            return Observable.empty()
          })
          .subscribe(onNext: { _ in
            //
//          }, onError: { error in
//            guard let moyaError = error as? MoyaError else { return }
//            let data = moyaError.response?.data
//
//            do {
//              let json = try JSONSerialization.jsonObject(with: data!) as! errorModel
//              print(json.errorCode)
//              print(json.errorMessage)
//            }
//            catch {
//              print("json parsing error")
//            }
          })
          .disposed(by: self.bag)

즉 flatmap으로 엮인 부분을 onError 처리 하지 않고 dispose 되게 하지 않음으로 스트림을 유지하면서 error처리가 가능하다! 이말입니다. 비교를 위해 onError에 있던 부분은 주석처리 했습니다.

 

이번에는 empty한 옵저버블을 리턴해줬지만 상황에 따라 다른 타입을 리턴해줘서 해당 부분에서 error가 있었는지 Bool로 처리할 수 도 있겠다는 생각이 들었습니다. 이거로 flag를 세우거나 할 수 있겠네요!