Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Got this error with retrofit2 & OkHttp3. Unable to resolve host "<host-name>": No address associated with hostname

Tags:

I am using the retrofit 2 and OkHttp3 to request data from server. I just added a offline cache code but It's not working as expected. I got the error "Unable to resolve host "<>": No address associated with hostname."

This occurs when It's try to get the retrieve data from the cache(when no internet connection). A code snippet is below.

public static Interceptor provideCacheInterceptor() {
    return new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Response response = chain.proceed(chain.request());

            // re-write response header to force use of cache
            CacheControl cacheControl = new CacheControl.Builder()
                    .maxAge(2, TimeUnit.MINUTES)
                    .build();

            return response.newBuilder()
                    .header(CACHE_CONTROL, cacheControl.toString())
                    .build();
        }
    };
}

public static Interceptor provideOfflineCacheInterceptor() {
    return new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();

            if (!hasNetwork) {
                CacheControl cacheControl = new CacheControl.Builder()
                        .onlyIfCached()
                        .maxStale(7, TimeUnit.DAYS)
                        .build();

                request = request.newBuilder()
                        .removeHeader("Pragma")
                        .cacheControl(cacheControl)
                        .build();
            }

            return chain.proceed(request);
        }
    };
}

private static Cache provideCache() {
    Cache cache = null;
    try {
        cache = new Cache(new File(AdeptAndroid.getInstance().getCacheDir(), "http-cache"),
                10 * 1024 * 1024); // 10 MB
    } catch (Exception e) {
        Log.d("Test", "Could not create Cache!");
    }
    return cache;
}

And finally a method which combine all of these is here.

private static OkHttpClient provideOkHttpClient() {
    return new OkHttpClient.Builder()
            .addInterceptor(provideHttpLoggingInterceptor())
            .addInterceptor(provideOfflineCacheInterceptor())
            .addNetworkInterceptor(provideCacheInterceptor())
            .cache(provideCache())
            .build();
}
like image 316
android_griezmann Avatar asked Jun 30 '16 05:06

android_griezmann


People also ask

How do I get error response in retrofit?

you can simply use "response. message(). toString()" which will give the same error string in a more readable format.


2 Answers

I had the same error in my project with kotlin, and I fixed it like this:

client.addInterceptor(provideOfflineCacheInterceptor(context))
client.addNetworkInterceptor(provideCacheInterceptor(context))

private fun provideOfflineCacheInterceptor(context: Context): Interceptor {
        return Interceptor { chain ->
            var request = chain.request()
            var cacheHeaderValue = if (!hasNetwork(context)!!){
                    "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 1
                } else {
                    "public, max-age=" + 5
                }
            request = request.newBuilder().header("Cache-Control", cacheHeaderValue).build()
            chain.proceed(request)
        }
    }

    private fun provideCacheInterceptor(context: Context): Interceptor {
        return Interceptor { chain ->
            val request = chain.request()
            var cacheHeaderValue = if (!hasNetwork(context)!!){
                    "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 1
                } else {
                    "public, max-age=" + 5
                }
            //request = request.newBuilder().build()
            val response = chain.proceed(request)
            response.newBuilder()
                    .removeHeader("Pragma")
                    .removeHeader("Cache-Control")
                    .header("Cache-Control", cacheHeaderValue)
                    .build()
        }
    }
like image 188
Ghizlane Lotfi Avatar answered Sep 22 '22 07:09

Ghizlane Lotfi


Your server response has a "Pragma: no-cache" header. You should remove this header in your response interceptor not your request interceptor.

In your current code you've removed it from the request interceptor.

Your provideCacheInterceptor() should look like this:

public static Interceptor provideCacheInterceptor() {
    return new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Response response = chain.proceed(chain.request());

            // re-write response header to force use of cache
            CacheControl cacheControl = new CacheControl.Builder()
                   .maxAge(2, TimeUnit.MINUTES)
                   .build();

           return response.newBuilder()
                    .header(CACHE_CONTROL, cacheControl.toString())
                    .removeHeader("Pragma")
                    .build();
        }
    };
}
like image 28
Ibrahim Avatar answered Sep 20 '22 07:09

Ibrahim