title: Kotlin Android Retrofit 2.6.0 with coroutines error handling
body: <p>I am using Retrofit 2.6.0 with coroutines for my web service call. I am getting the API response properly with all response codes (success &amp; error cases). My Issue is when I disconnect the internet(Wifi/mobile data) in between an API call, from the code that I have written, the error is not getting caught properly. The errors most of the time are ConnectException and SocketException.</p>
  
  <p>I have tried to catch the error using interceptor and also in from the ViewModel where initiated my call as well. but here as well, the exception is not getting caught and handled.</p>
  
  <pre><code>//ApiService
  @GET(ApiUrl.API_DASHBOARD)
      suspend fun getHomeUiDetails(@Header("Authorization") authHeader: String): Response&lt;HomeDetailsResponse&gt;
  
  //ConnectionBridge
  suspend fun getHomeUiDetails(authToken: String): Response&lt;HomeDetailsResponse&gt; {
          return ApiServiceGenerator.BASIC_CLIENT_CONTRACT.getHomeUiDetails(authToken)
      }
  
  // ViewModel
  viewModelScope.launch(Dispatchers.IO) {
     val apiResponse = ApiConnectionBridge.getHomeUiDetails(SharedPrefUtils.getAuthToken(context))
          if (apiResponse.isSuccessful) {
             // success case
          } else {
              // error case
          }
  }
  
  object ApiServiceGenerator {
  
      val BASIC_CLIENT_CONTRACT: ApiService = ApiClient
          .getContract(
              ApiService::class.java,
              true,
              BuildConfig.BASE_URL
          )
  }
  
  object ApiClient {
  
      fun &lt;T&gt; getContract(clazz: Class&lt;T&gt;, isAuth: Boolean, baseUrl: String): T {
          return getRetrofitBuilder(baseUrl, getContractBuilder(isAuth)).create(clazz)
      }
  
      private fun getRetrofitBuilder(baseUrl: String, builder: OkHttpClient.Builder): Retrofit {
          val gson = GsonBuilder().serializeNulls().create()
  
          val loggingInterceptor = HttpLoggingInterceptor()
          loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
  
          val okHttpClient = OkHttpClient.Builder()
              .addInterceptor { chain -&gt;
                  val original = chain.request()
  
                  // Customize the request
                  val request = original.newBuilder()
                  request.header("Content-Type", "application/x-www-form-urlencoded")
  
                  var response: Response? = null
                  try {
                      response = chain.proceed(request.build())
                      response.cacheResponse()
  
                      // Customize or return the response
  
                      response!!
                  } catch (e: ConnectException) {
                              Log.e("RETROFIT", "ERROR : " + e.localizedMessage)
                      chain.proceed(original)
                  } catch (e: SocketException) {
                      Log.e("RETROFIT", "ERROR : " + e.localizedMessage)
                      chain.proceed(original)
                  } catch (e: IOException) {
                      Log.e("RETROFIT", "ERROR : " + e.localizedMessage)
                      chain.proceed(original)
                  } catch (e: Exception) {
                      Log.e("RETROFIT", "ERROR : " + e.localizedMessage)
                      chain.proceed(original)
                  }
              }
              //            .cache(cache)
              .eventListener( object : EventListener() {
                  override fun callFailed(call: Call, ioe: IOException) {
                      super.callFailed(call, ioe)
                  }
  
              })
              .addInterceptor(loggingInterceptor)
              .readTimeout(60, TimeUnit.SECONDS)
              .connectTimeout(60, TimeUnit.SECONDS)
              .build()
  
          return Retrofit.Builder()
              .baseUrl(baseUrl)
              .client(okHttpClient)//getUnsafeOkHttpClient()
              .addConverterFactory(GsonConverterFactory.create(gson))
              .build()
      }
  }
  
  </code></pre>
  
  <p>The stack trace:</p>
  
  <pre><code>2019-08-02 14:15:12.819 4157-4288/com.my.app E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-3
  Process: com.my.app, PID: 4157
  java.net.ConnectException: Failed to connect to my_url
      at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.java:248)
      at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:166)
      at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:257)
      at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135)
      at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:114)
      at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
      at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
      at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
      at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126)
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
      at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:213)
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
      at com.my.app.network.ApiClient$getRetrofitBuilder$okHttpClient$1.intercept(ApiClient.kt:50)
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
      at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254)
      at okhttp3.RealCall$AsyncCall.execute(RealCall.java:200)
      at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
      at java.lang.Thread.run(Thread.java:764)
   Caused by: java.net.ConnectException: failed to connect to my_url (port 80) from /:: (port 0) after 60000ms: connect failed: ENETUNREACH (Network is unreachable)
      at libcore.io.IoBridge.connect(IoBridge.java:137)
      at java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:137)
      at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:390)
      at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:230)
      at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:212)
      at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:436)
      at java.net.Socket.connect(Socket.java:621)
      at okhttp3.internal.platform.AndroidPlatform.connectSocket(AndroidPlatform.java:73)
      at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.java:246)
      at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:166) 
      at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:257) 
      at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135) 
      at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:114) 
      at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42) 
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) 
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) 
      at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93) 
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) 
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) 
      at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93) 
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) 
      at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126) 
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) 
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) 
      at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:213) 
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) 
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) 
      at com.my.app.network.ApiClient$getRetrofitBuilder$okHttpClient$1.intercept(ApiClient.kt:50) 
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) 
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) 
      at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254) 
      at okhttp3.RealCall$AsyncCall.execute(RealCall.java:200) 
      at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32) 
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
      at java.lang.Thread.run(Thread.java:764) 
   Caused by: android.system.ErrnoException: connect failed: ENETUNREACH (Network is unreachable)
      at libcore.io.Linux.connect(Native Method)
      at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:118)
      at libcore.io.IoBridge.connectErrno(IoBridge.java:168)
      at libcore.io.IoBridge.connect(IoBridge.java:129)
      at java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:137) 
      at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:390) 
      at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:230) 
      at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:212) 
      at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:436) 
      at java.net.Socket.connect(Socket.java:621) 
      at okhttp3.internal.platform.AndroidPlatform.connectSocket(AndroidPlatform.java:73) 
      at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.java:246) 
      at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:166) 
      at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:257) 
      at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135) 
      at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:114) 
      at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42) 
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) 
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) 
      at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93) 
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) 
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) 
      at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93) 
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) 
      at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126) 
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) 
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) 
      at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:213) 
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) 
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) 
      at com.my.app.network.ApiClient$getRetrofitBuilder$okHttpClient$1.intercept(ApiClient.kt:50) 
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) 
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) 
      at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254) 
      at okhttp3.RealCall$AsyncCall.execute(RealCall.java:200) 
      at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32) 
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
      at java.lang.Thread.run(Thread.java:764)
  </code></pre>