Skip to content

Instantly share code, notes, and snippets.

@AliAkberAakash
Last active November 25, 2020 14:16
Show Gist options
  • Save AliAkberAakash/80cab6092e38d8acbe3c7bb542de0c37 to your computer and use it in GitHub Desktop.
Save AliAkberAakash/80cab6092e38d8acbe3c7bb542de0c37 to your computer and use it in GitHub Desktop.
package com.example.helloworld.core.data.network
import android.content.Context
import com.example.helloworld.utils.ConnectivityAndInternetAccess
import retrofit2.*
import java.io.IOException
import java.lang.Exception
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type
class ResponseErrorHandlingCallAdapterFactory(private val context: Context): CallAdapter.Factory() {
companion object {
fun create(context: Context) : CallAdapter.Factory =
ResponseErrorHandlingCallAdapterFactory(
context
)
}
override fun get(returnType: Type, annotations: Array<Annotation>, retrofit: Retrofit): CallAdapter<*, *> {
check(returnType is ParameterizedType) { "Response must have generic type (e.g., Response<MyDataModel>)" }
val responseType = getParameterUpperBound(0, returnType)
return ResponseCallAdapterWrapper<Any>(context, retrofit, responseType)
}
private inner class ResponseCallAdapterWrapper<R>(val context: Context,
val retrofit: Retrofit,
val responseType: Type
): CallAdapter<R, Response<R>> {
override fun responseType(): Type = responseType
@Suppress("UNCHECKED_CAST")
override fun adapt(call: Call<R>): Response<R> {
var result : Response<R> ? = null
call.enqueue(object : Callback<R>{
override fun onResponse(call: Call<R>, response: Response<R>) {
result = response
}
override fun onFailure(call: Call<R>, t: Throwable) {
throw asRetrofitException(context, t, call.request().url.host, retrofit)
}
})
return result!!
}
}
private fun asRetrofitException(context: Context, throwable: Throwable, host: String, retrofit: Retrofit):
RetrofitException {
// We had non-200 http error
if (throwable is HttpException) {
val response = throwable.response()
if (throwable.code() == 422) {
// on out api 422's get metadata in the response. Adjust logic here based on your needs
return RetrofitException.httpErrorWithObject(response?.raw()?.request?.url.toString(), response, retrofit)
} else {
return RetrofitException.httpError(response?.raw()?.request?.url.toString(), response, retrofit)
}
}
// A network error happened
if(!ConnectivityAndInternetAccess.isConnectedToInternet(context, host)) {
return RetrofitException.parseIOException(context, throwable, host)
}
else if (throwable is IOException) {
return RetrofitException.parseIOException(context,throwable, host)
}
// We don't know what happened. We need to simply convert to an unknown error
return RetrofitException.unexpectedError(throwable)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment