简体   繁体   中英

RxSwift - How to handle different error scenarios with Observable.zip

I have this code:

    ...
    let minMaxReq = networkProvider.getMinMaxAmortization(id: id)
    let emitExtractReq = networkProvider.getEmitExtract(id: id)

    self.isLoading.accept(true)

    Observable.zip(minMaxReq.asObservable(), emitExtractReq.asObservable()) { (minMaxResp, emitExtractResp) in
            return (minMaxResp, emitExtractResp)
        }.subscribe(onNext: { [weak self] responses in

            let minMaxResp = responses.0
            let emitExtractResp = responses.1

            guard let self = self else { return }

            self.isLoading.accept(false)
            self.getMinMaxAmortizationResponse.accept(minMaxResp)
            self.receiptsCNH.accept(emitExtractResp)

        }, onError: { [weak self] error in

            self?.isLoading.accept(false)
            self?.receivedError.accept(error)

        }).disposed(by: disposeBag)

In this case all errors from both requests will end up in the onError closure, how can I handle the error from minMaxReq in a different onError closure?

My goal is to make the 2 requests at the same time but handle their error with different closures. How can I achieve this? thanks

Have you tried the materialize operator? Maybe it can be useful for the implementation you need. Annex an example of how it is usually used:

let valid = network.getToken(apikey)
            .flatMap{ token in self.verifyToken(token).materialize()}
            .share()

valid
    .compactMap { $0.element }
    .subscribe(onNext: { data in print("token is valid:", data) })
    .disposed(by: disposeBag)

valid
    .compactMap { $0.error?.localizedDescription }
    .subscribe(onNext: { data in print("token is not valid:", data) })
    .disposed(by: disposeBag)

In that way, you could divide the stream into two and give it the appropriate treatment.

Another option might be to manipulate the error event in the minMaxReq operation. Something similar to:

let minMaxReq = networkProvider.getMinMaxAmortization(id: id)
                        .catchError({ error in Observable.empty()
                        .do(onCompleted: { /* Do anything with no side effect*/  }) })

let emitExtractReq = networkProvider.getEmitExtract(id: id)

Observable.zip(...)

Here is an article that explains more detail Handling Errors in RxSwift

I found this solution helpful for me RxSwift zip operator when one observable can fail

Need to catch error before add to zip

let request1 = usecase.request1().asObservable()
let request2 = usecase.request2().catchErrorJustReturn([]).asObservable() // fetching some not so important data which are just good to have.Return empty array on error
Observable.zip(request1,request2)..observeOn(MainScheduler.instance)
   .subscribe(
      onNext: { //success code },
      onError: { _ in //error code}).disposeBy(bag:myDisposeBag)

But I changed a bit the final:

let request2 = usecase.request2().catchError { _ in
            return .just([])
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM