Forked from ivan-anic/RxErrorHandlingCallAdapterFactory.kt
Created
December 27, 2018 07:19
-
-
Save Dadoufi/fbf6decb9aaa25257e658104a6ef66d2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.degordian.common.data.retrofit | |
import android.util.Log | |
import io.reactivex.* | |
import retrofit2.Call | |
import retrofit2.CallAdapter | |
import retrofit2.HttpException | |
import retrofit2.Retrofit | |
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory | |
import java.io.IOException | |
import java.lang.reflect.Type | |
/** | |
* Created by tomislav on 09/01/2017. | |
* Updated to Kotlin on 10/07/18. | |
*/ | |
class RxErrorHandlingCallAdapterFactory private constructor() : CallAdapter.Factory() { | |
private val original: RxJava2CallAdapterFactory = RxJava2CallAdapterFactory.create() | |
override fun get(returnType: Type, annotations: Array<Annotation>, retrofit: Retrofit): CallAdapter<*, *>? { | |
val wrapped = original.get(returnType, annotations, retrofit) as CallAdapter<out Any, *> | |
return RxCallAdapterWrapper(retrofit, wrapped) | |
} | |
private class RxCallAdapterWrapper<R>(val retrofit: Retrofit, | |
val wrapped: CallAdapter<R, *> | |
) : CallAdapter<R, Any> { | |
override fun responseType(): Type { | |
return wrapped.responseType() | |
} | |
@Suppress("UNCHECKED_CAST") | |
override fun adapt(call: Call<R>): Any { | |
wrapped.adapt(call) | |
val result = wrapped.adapt(call) | |
when (result) { | |
is Observable<*> -> { | |
return (wrapped.adapt(call) as Observable<R>) | |
.onErrorResumeNext { throwable: Throwable -> Observable.error { asRetrofitException(throwable, retrofit) } } | |
} | |
is Single<*> -> { | |
return (wrapped.adapt(call) as Single<R>) | |
.onErrorResumeNext({ throwable: Throwable -> Single.error(asRetrofitException(throwable, retrofit)) }) | |
} | |
is Maybe<*> -> { | |
return (wrapped.adapt(call) as Maybe<R>) | |
.onErrorResumeNext({ throwable: Throwable -> Maybe.error(asRetrofitException(throwable, retrofit)) }) | |
} | |
is Completable -> { | |
return (wrapped.adapt(call) as Completable) | |
.onErrorResumeNext { throwable: Throwable -> Completable.error(asRetrofitException(throwable, retrofit)) } | |
} | |
is Flowable<*> -> { | |
return (wrapped.adapt(call) as Flowable<R>) | |
.onErrorResumeNext({ throwable: Throwable -> Flowable.error(asRetrofitException(throwable, retrofit)) }) | |
} | |
else -> return result | |
} | |
} | |
} | |
companion object { | |
fun create(): CallAdapter.Factory { | |
return RxErrorHandlingCallAdapterFactory() | |
} | |
private fun asRetrofitException(throwable: Throwable, retrofit: Retrofit): RetrofitException { | |
Log.d("RxErrorHandler", throwable.message) | |
throwable.printStackTrace() | |
// We had non-200 http error | |
if (throwable is HttpException) { | |
val response = throwable.response() | |
return RetrofitException.httpError(response.raw().request().url().toString(), response, retrofit) | |
} | |
// A network error happened | |
return if (throwable is IOException) { | |
RetrofitException.networkError(throwable) | |
} else RetrofitException.unexpectedError(throwable) | |
// We don't know what happened. We need to simply convert to an unknown error | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment