OkHttp3 SocketTimeoutException (in Android app) -- How to set read timeout for asynchronous request?

15,207

Instead of

m_client = new OkHttpClient();

you should create the client using a builder like:

m_client = new OkHttpClient.Builder()
        .connectTimeout(10, TimeUnit.SECONDS)
        .writeTimeout(10, TimeUnit.SECONDS)
        .readTimeout(30, TimeUnit.SECONDS)
        .build();

When you create the client like this each Request executed whit this client (using m_client.newCall(...)) will use the timeouts specified in the builder.

Share:
15,207

Related videos on Youtube

Alyoshak
Author by

Alyoshak

I am responsible for mobile device and laptop/desktop-based software here at ALL In Learning, Inc. (Denton, Texas). Right now I maintain 2 iOS apps and an Android app that integrate with our web solutions, and some desktop software (OSX and Windows) that provide image processing services either via WASM or Chrome native messaging. The Android app uses JNI to use our custom NDK library.

Updated on June 04, 2022

Comments

  • Alyoshak
    Alyoshak about 2 years

    I keep getting a java.net.SocketTimeoutException when attempting an OkHttp3 asynchronous Get. This suggests that I haven't set the read timeout value high enough (I think the default is 10 seconds).

    The larger question is "How to prevent this exception?" but, unless someone has a better initial strategy, my immediate question is, "How to set a read timeout value for the request?"

    In my code I've used the information from the Okttp Recipes page here

    Notice the first two lines of my try-catch are commented out. That's because I cannot use the kind of builder (one capable of setting a timeout value, OkHttpClient.Builder) that I need in order to add header info (Request.Builder) .

    My code looks like this:

        m_client = new OkHttpClient();
    
    
        try
        {
            //OkHttpClient.Builder bldr = m_client.newBuilder();
            //bldr.readTimeout(0, TimeUnit.SECONDS);
    
            Request.Builder reqBuilder = new Request.Builder();
    
            reqBuilder.addHeader("authorization", getToken());
    
            Request request = reqBuilder.url("http://plusdev.kooklah.com/api/v2_1/items/get").build();
    
            m_client.newCall(request).enqueue(new Callback()
            {
                @Override
                public void onFailure(Call call, IOException e)
                {
                    Log.i("Logit", "Inside onFailure() -- IOException: " + e.getMessage() + " ----- stack trace: " + UtilGen.exceptionToString(e));
    
                    runOnUiThread(new Runnable()
                    {
                        @Override
                        public void run()
                        {
                           // do stuff on UI thread
                        }
                    });
                }
    
                @Override
                public void onResponse(Call call, final Response responseIn)
                {
                    try
                    {
                        m_sServerResponse = responseIn.body().string();
                    }
                    catch (Exception ex)
                    {
                        Log.i("LogIt", "          ---Inside onResponse() -- Exception occurred. ex: " + ex.toString());
                    }
    
                    runOnUiThread(new Runnable()
                    {
                        @Override
                        public void run()
                        {
                            Log.i("LogIt", "          ---Inside onResponse() -- inside run().");
                            if (!m_sServerResponse.isEmpty())
                            {
                                Log.i("LogIt", "          ---Inside onResponse() -- inside run() -- Success");
                                processDownloadedAssessments(m_sServerResponse);
                            }
                        }
                    });
                }
            });
        }
        catch (Exception ex)
        {
            Log.i("LogIt", "ex: " + ex.getMessage());
        }
    

    I found a reported issue that seems directly related, here, on the okhttp github site. There's even a recommendation to set the read timeout, which as mentioned above has been commented out because I cannot figure how to bring that kind of builder to bear on an async request as described on the Recipe page.

    The stack trace for my exception is below, but be aware that most of the time I don't get the exception. Stack trace:

    01-19 14:04:52.192: I/LogIt(25650): Inside onFailure() -- IOException: null ----- stack trace: java.net.SocketTimeoutException
    01-19 14:04:52.192: I/LogIt(25650):     at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
    01-19 14:04:52.192: I/LogIt(25650):     at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:37)
    01-19 14:04:52.192: I/LogIt(25650):     at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:237)
    01-19 14:04:52.192: I/LogIt(25650):     at okio.Okio$2.read(Okio.java:138)
    01-19 14:04:52.192: I/LogIt(25650):     at okio.AsyncTimeout$2.read(AsyncTimeout.java:236)
    01-19 14:04:52.192: I/LogIt(25650):     at okio.RealBufferedSource.indexOf(RealBufferedSource.java:325)
    01-19 14:04:52.192: I/LogIt(25650):     at okio.RealBufferedSource.indexOf(RealBufferedSource.java:314)
    01-19 14:04:52.192: I/LogIt(25650):     at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:210)
    01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http1.Http1Codec.readResponse(Http1Codec.java:191)
    01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http1.Http1Codec.readResponseHeaders(Http1Codec.java:132)
    01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:54)
    01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45)
    01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
    01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
    01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
    01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
    01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120)
    01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
    01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:179)
    01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.RealCall$AsyncCall.execute(RealCall.java:129)
    01-19 14:04:52.192: I/LogIt(25650):     at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
    01-19 14:04:52.192: I/LogIt(25650):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    01-19 14:04:52.192: I/LogIt(25650):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    01-19 14:04:52.192: I/LogIt(25650):     at java.lang.Thread.run(Thread.java:818)
    
  • Alyoshak
    Alyoshak over 7 years
    I smell what you're cooking. Have to shut down for a bit, but will try this asap. May be tomorrow. Thanks.
  • Alyoshak
    Alyoshak over 7 years
    That was my problem, I was not using the build() call on the OkHttpClient builder after setting its timeouts.
  • Beatrice Lin
    Beatrice Lin almost 7 years
    What is their correspond Exception when timeout?

Related