None of the answers quite worked for me but they led me in the right direction. See below how I did it in Kotlin.
You can either throw the exceptions in the ErrorInterceptor
and catch them in your api call function:
class ErrorInterceptor : Interceptor {
override fun intercept(chain: Chain): Response {
val request = chain.request()
try {
val response = chain.proceed(request)
val bodyString = response.body!!.string()
return response.newBuilder()
.body(bodyString.toResponseBody(response.body?.contentType()))
.build()
} catch (e: Exception) {
when (e) {
is SocketTimeoutException -> {
throw SocketTimeoutException()
}
// Add additional errors... //
}
}
}
Or bundle exceptions with a response object; something like this:
class ErrorInterceptor : Interceptor {
override fun intercept(chain: Chain): Response {
val request = chain.request()
try {
val response = chain.proceed(request)
val bodyString = response.body!!.string()
return response.newBuilder()
.body(bodyString.toResponseBody(response.body?.contentType()))
.build()
} catch (e: Exception) {
var msg = ""
val interceptorCode: Int
when (e) {
is SocketTimeoutException -> {
msg = "Socket timeout error"
interceptorCode = 408
}
// Add additional errors... //
}
return Response.Builder()
.request(request)
.protocol(Protocol.HTTP_1_1)
.code(interceptorCode)
.message(msg)
.body("{${e}}".toResponseBody(null)).build()
}
}
}
Add the ErrorInterceptor
to your okHttpClient
:
okHttpClient.newBuilder()
.addInterceptor(ErrorInterceptor())
.connectTimeout(10, TimeUnit.SECONDS)
// ... //
.build()
And then something like this in your repository layer:
suspend fun makeAPIRequest(): Resource<ApiResponse> {
return withContext(ioDispatcher) {
var response: Response<ApiResponse>? = null
try {
response = getResponse()
// Do additional ops on response here //
} catch (e: Exception) {
// Exceptions thrown in ErrorInterceptor will propagate here
}
}
}