Handle exceptions thrown by a custom okhttp Interceptor in Kotlin Coroutines
You may catch the exception in your custom Interceptor
and return an empty response with some specific message
and code
. I have implemented a custom Interceptor
to handle the situation like when you do not have or slow internet connection etc... Actually coroutine's suspend functions throws exception when dealing with network calls. In my experience, you can follow 2 approaches. 1. wrap your all network call in try...catch
or 2. create a custom Interceptor
and handle exceptions there and return some specific response.
Approach 1:
try {
webservice.login(username, password)
} catch (e: Exception) {
//...
}
Approach 2:
Create a custom Interceptor
and handle exception there.
class LoggingInterceptor : Interceptor {
@Throws(Exception::class)
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
try {
val response = chain.proceed(request)
val bodyString = response.body()!!.string()
return response.newBuilder()
.body(ResponseBody.create(response.body()?.contentType(), bodyString))
.build()
} catch (e: Exception) {
e.printStackTrace()
var msg = ""
when (e) {
is SocketTimeoutException -> {
msg = "Timeout - Please check your internet connection"
}
is UnknownHostException -> {
msg = "Unable to make a connection. Please check your internet"
}
is ConnectionShutdownException -> {
msg = "Connection shutdown. Please check your internet"
}
is IOException -> {
msg = "Server is unreachable, please try again later."
}
is IllegalStateException -> {
msg = "${e.message}"
}
else -> {
msg = "${e.message}"
}
}
return Response.Builder()
.request(request)
.protocol(Protocol.HTTP_1_1)
.code(999)
.message(msg)
.body(ResponseBody.create(null, "{${e}}")).build()
}
}
}
I have created gist for complete implementation of LoggingInterceptor
with print logs of request and response. LoggingInterceptor
You should subclass IOException
and use that to send information from your interceptors to your calling code.
We consider other exceptions like IllegalStateException
to be application crashes and do not send them over thread boundaries because we don’t want to burden most callers with catching them.