Yuchen
Yuchen

Reputation: 33036

How to map one error to a different error with RxSwift

Is it possible to map the error type with RxSwift?

For example, I have a helper function like this:

enum InternalError: Error {
   case fooError
   case barError
}

private func helper() -> Observable<MyData> {
    // ... 
}

enum ServiceError: Error {
    case fatalError(message: String)
    case warning(message: String)
}

I am hoping that we can do sth like this, notice the following mapError doesn't exist:

func getData() -> Observable<MyData> {
    helper().mapError({ error: InternalError -> ServiceError
        switch error {
            case .fooError: 
                return ServiceError.fatalError(message: "This is bad.")
            case .barError:
                return ServiceError.warning(message: "Be careful.")
        }
    })
}

Is it possible? Or is it a bad idea in general?

Upvotes: 5

Views: 2916

Answers (1)

Timofey Solonin
Timofey Solonin

Reputation: 1403

What you described in you problem is impossible to do by returning an error because the return type of your function is an Observable<MyData>. There are two solutions:

You could define a enum Result<T> with .success(T) and .error(Swift.Error) and return Observable<Result<MyData>> where you would handle your errors as follows:

helper().catchError{ error in
            guard let error = error as? InternalError else { throw UnknownError() }
            switch error {
                case .fooError:
                    return Observable.just(
                        Result.error(
                            ServiceError.fatalError(message: "This is bad.")
                        )
                    )
                case .barError:
                    return Observable.just(
                        Result.error(
                            ServiceError.warning(message: "Be careful.")
                        )
                    )
            }
        }

Or you could simply rethrow by substituting return Observable... with a throw which I personally think is better than a Result<T> overhead.

Upvotes: 2

Related Questions