RxSwift: `catchError` behavior only tied to latest observable sequence???

Hey guys,

I have problems in understanding error catching and continuing the observable sequence in case of an error.

I now have some sequences like this one:

function doManyThings() -> Observable<AnyType> {
    return crazyFunction
        .flatMap(functionThatCanErrorOut)
        .flatMap(functionThatCanErrorOut)
        .flatMap(functionThatCanErrorOut)
        .flatMap(functionThatCanErrorOut)
        .flatMap(functionThatCanErrorOut)
}

button.rx_tap
    .flatMap(doManyThings)
    .catchError { handleErrors($0) }
    .subscribeNext { input in
        // do something
    }

Is it not possible to catch all the errors in a central place without doing subscribeError which cancels the subscription entirely??? I now have the case that .catchError() is called, no matter what error, but when I tap button a second time, nothing happens because it seems the subscription is canceled.

How do you solve this kind of issue?

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Comments: 21 (1 by maintainers)

Most upvoted comments

Based on answer the solution is:

    @warn_unused_result(message="http://git.io/rxs.uo")
    public func flatMapLatest<O: ObservableConvertibleType>(selector: (Self.E) throws -> O,
                              onError: (ErrorType throws -> Void)) -> RxSwift.Observable<O.E> {

        return flatMapLatest({ x in
            try selector(x).asObservable().catchError { error in
                try onError(error)
                return Observable.never()
            }
        })
    }

And it used like this

button.rx_tap
    .flatMapLatest(doManyThings, onError: { 
          //handle Error
    }).subscribeNext { input in
        // do something
    }

But I personally prefer:

    @warn_unused_result(message="http://git.io/rxs.uo")
    public func catchErrorAndContinue(handler: (ErrorType) throws -> Void) -> RxSwift.Observable<Self.E> {
        return self.catchError { error in
            try handler(error)
            return Observable.error(error)
        }.retry()
    }

This is used like this:

button.rx_tap
    .flatMapLatest { doManyThings }
    .catchErrorAndContinue {
        // handle error
    }.subscribeNext { input in
        // do something
    }