title: Distinguish between Connect Timeout and Read Timeout with okhttp
body: <p>I am using okhttp with ribbon using spring.
  I wish to retry on another service instance on connect timeout but not on read timeout(for obvious reasons). This retry will be handled by a custom ribbon retry handler. But to do the above, I need to distinguish between read and connect timeouts.
  The behaviour with okhttp is as follows:</p>
  
  <ul>
  <li><p>On read timeout: </p>
  
  <pre><code>java.net.SocketTimeoutException: timeout
      at okio.Okio$3.newTimeoutException(Okio.java:212)
      at okio.AsyncTimeout.exit(AsyncTimeout.java:288)
      at okio.AsyncTimeout$2.read(AsyncTimeout.java:242)
      at okio.RealBufferedSource.indexOf(RealBufferedSource.java:325)
      at okio.RealBufferedSource.indexOf(RealBufferedSource.java:314)
      at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:210)
      at okhttp3.internal.http.Http1xStream.readResponse(Http1xStream.java:184)
      at okhttp3.internal.http.Http1xStream.readResponseHeaders(Http1xStream.java:125)
      at okhttp3.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:775)
      at okhttp3.internal.http.HttpEngine.access$200(HttpEngine.java:86)
      at okhttp3.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:760)
      at okhttp3.internal.http.HttpEngine.readResponse(HttpEngine.java:613)
      at okhttp3.RealCall.getResponse(RealCall.java:244)
      at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:201)
      at com.bluejeans.sample.test.OkHttpConnect$1.intercept(OkHttpConnect.java:25)
      at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:190)
      at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:163)
      at okhttp3.RealCall.execute(RealCall.java:57)
      at com.bluejeans.sample.test.OkHttpConnect.main(OkHttpConnect.java:39)
  Caused by: java.net.SocketTimeoutException: Read timed out
      at java.net.SocketInputStream.socketRead0(Native Method)
      at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
      at java.net.SocketInputStream.read(SocketInputStream.java:170)
      at java.net.SocketInputStream.read(SocketInputStream.java:141)
      at okio.Okio$2.read(Okio.java:140)
      at okio.AsyncTimeout$2.read(AsyncTimeout.java:238)
      ... 16 more
  </code></pre></li>
  <li><p>On connect timeout: </p>
  
  <pre><code> java.net.SocketTimeoutException: connect timed out
      at java.net.PlainSocketImpl.socketConnect(Native Method)
      at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:345)
      at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
      at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
      at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
      at java.net.Socket.connect(Socket.java:589)
      at okhttp3.internal.Platform.connectSocket(Platform.java:121)
      at okhttp3.internal.io.RealConnection.connectSocket(RealConnection.java:185)
      at okhttp3.internal.io.RealConnection.buildConnection(RealConnection.java:170)
      at okhttp3.internal.io.RealConnection.connect(RealConnection.java:111)
      at okhttp3.internal.http.StreamAllocation.findConnection(StreamAllocation.java:187)
      at okhttp3.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:123)
      at okhttp3.internal.http.StreamAllocation.newStream(StreamAllocation.java:93)
      at okhttp3.internal.http.HttpEngine.connect(HttpEngine.java:296)
      at okhttp3.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
      at okhttp3.RealCall.getResponse(RealCall.java:243)
      at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:201)
      at com.bluejeans.sample.test.OkHttpConnect$1.intercept(OkHttpConnect.java:25)
      at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:190)
      at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:163)
      at okhttp3.RealCall.execute(RealCall.java:57)
      at com.bluejeans.sample.test.OkHttpConnect.main(OkHttpConnect.java:39)
  </code></pre></li>
  </ul>
  
  <p>Deciding based on the exception message doesn't seem like a good idea. What is the recommended way to achieve this? </p>