Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SocketTimeoutException in Retrofit

People also ask

What is a SocketTimeoutException?

SocketTimeoutException: Connection timed out) means that it takes too long to get respond from other device and your request expires before getting response.

How do I increase the connection timeout in retrofit?

You can set timeouts on the underlying HTTP client. If you don't specify a client, Retrofit will create one with default connect and read timeouts. To set your own timeouts, you need to configure your own client and supply it to the RestAdapter. Builder .

Why do we get SocketTimeoutException?

As you may suspect based on the name, the SocketTimeoutException is thrown when a timeout occurs during a read or acceptance message within a socket connection.


Increase the time if the fetching is taking more time use this code it worked for me

 OkHttpClient client = new OkHttpClient.Builder()
            .connectTimeout(100, TimeUnit.SECONDS)
            .readTimeout(100,TimeUnit.SECONDS).build();
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("yourbaseurl").client(client)
            .addConverterFactory(GsonConverterFactory.create(new  Gson())).build();

hay this is a work around not the best practice , from comments down, Back end should not take this long and user must be notified with error or try again message


Preventing SocketTimeoutException is beyond our limit...One way to effectively handle it is to define a connection timeout

Example for

retrofit 1.9.0

restadapter = new RestAdapter.Builder().setEndpoint(HOST).setLogLevel(RestAdapter.LogLevel.FULL).setClient(new OkHttpClient()
                .setReadTimeout(30, TimeUnit.SECONDS)
                .setConnectTimeout(30, TimeUnit.SECONDS)).build();

retrofit 2.0.0

OkHttpClient client = new OkHttpClient();
client.setConnectTimeout(10, TimeUnit.SECONDS);
client.setReadTimeout(30, TimeUnit.SECONDS);
retrofit = new Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .client(client)
        .build();

retrofit 2.4.0

// setting custom timeouts
    OkHttpClient.Builder client = new Builder();
    client.connectTimeout(15, TimeUnit.SECONDS);
    client.readTimeout(15, TimeUnit.SECONDS);
    client.writeTimeout(15, TimeUnit.SECONDS);

    if (retrofit == null) {
      retrofit = new Retrofit.Builder()
          .baseUrl(BASE_URL)
          .addConverterFactory(GsonConverterFactory.create())
          .client(client.build())
          .build();
    }
    return retrofit;
  }

I'm facing the same issue with some request. Usually get this when there's an active request and got SocketTimeoutException due to got disconnected from the network. After that, same request always throws SocketTimeoutException.

I built my OkHttpClient using the code below as suggested in "java.net.SocketTimeoutException from HTTP/2 connection leaves dead okhttp clients in pool":

val builder = OkHttpClient.Builder()
    .cache(cache)
    .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
    .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
    .connectionPool(ConnectionPool(0, 5, TimeUnit.MINUTES))
    .protocols(listOf(Protocol.HTTP_1_1))

Setting the connectionPool and protocols will fix SocketTimeoutException caused by Timeouts.

This is a temporary fix and hopefully will get resolved in future versions of OkHttp used by Retrofit.


It's works for me to catch and throw a new IOException

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Response response = null;
        try {
            response = chain.proceed(request);
        }catch (SocketTimeoutException e){
            throw new IOException();
        }
        String url = request.url().url().toString();
        if (existInWhiteList(url)) {
            return response;
        }
        return logResponse(response);
    }

and you can add your own info in this new IOException();