androidretrofitrx-java2rx-kotlin2

RxJava2 Error Handling Wrapper For Retrofit Service


I need to handle error globally in my application for network service, i am using Rxjava2CallAdapterFactory in my retrofit service. So In order to handle error globally i searched through various sites and i got a solution. But i do know how this works.

class RxErrorAdapter private constructor() : CallAdapter.Factory() {

    private val original = RxJava2CallAdapterFactory.create()

    override fun get(returnType: Type, annotations: Array<Annotation>, retrofit: Retrofit): CallAdapter<*, *>? {
        return Wrapper<Any>(original.get(returnType, annotations, retrofit)
                ?: return null)
    }

    private class Wrapper<R>(private val wrapped: CallAdapter<R, *>) : CallAdapter<R, Any> {

        override fun responseType(): Type {
            return wrapped.responseType()
        }

        override fun adapt(call: Call<R>): Any {
            val result = wrapped.adapt(call)
        }
    }


    companion object {
        fun create(): CallAdapter.Factory {
            return RxErrorAdapter()
        }
    }
}

Can anyone explain on this ?


Solution

  • Since RxJava2CallAdapter already knows how to adapt a return type Call<T> to Observable<T>, Completable and other Rx types, RxErrorCallAdapterFactory asks the original factory RxJava2CallAdapterFactory to create such "original" RxJava2CallAdapter. Then RxErrorCallAdapterFactory creates its own CallAdapter - RxCallAdapterWrapper, with that original adapter inside.

    So RxErrorCallAdapterFactory gives out RxCallAdapterWrapper which first delegates to the original RxJava2CallAdapter to convert Call<User> to Observable<User>, and then applies onErrorResumeNext() operator ontop of Observable<User>.

    When an error occurs during network request (e.g. 400 Bad Request from the server) it will be propagated to that onErrorResumeNext() where you can apply your error-mapping logic. In this case onErrorResumeNext() takes Throwable and returns Observable that signals onError() with mapped Throwable.

    Basically, if original CallApater returns Observable.just(User()), wrapper CallAdapter will return this:

        Observable.just(User())
            .onErrorResumeNext { throwable -> 
                Observable.error(map(throwable))
            }