Apollo-android: HTTP Cache fails to parse response when HttpLoggingInterceptor set to OkHttp client.

Created on 23 Aug 2017  路  5Comments  路  Source: apollographql/apollo-android

How to reproduce (on sample app, using apollo 0.4.0):

1 - Add the commonly used HttpLogginInterceptor to OkHttp client:
@Override public void onCreate() { super.onCreate(); HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient okHttpClient = new OkHttpClient.Builder() .addInterceptor(interceptor) .build();

2 - Add DiskLruHttpCacheStore to apollo client:
DiskLruHttpCacheStore store = new DiskLruHttpCacheStore(getCacheDir(), 1024*1024); apolloClient = ApolloClient.builder() .serverUrl(BASE_URL) .okHttpClient(okHttpClient) .normalizedCache(normalizedCacheFactory, cacheKeyResolver) .httpCacheStore(store) .defaultHttpCachePolicy(HttpCachePolicy.CACHE_FIRST.expireAfter(5, TimeUnit.MINUTES)) .build();

3 - On GitHuntFeedActivity set FEED_SIZE constant to 1 (for temporal fix on invalid response when more than 1 item is loaded).

Expected:
Response is cached on disk, and displayed on screen.

Result:
08-23 09:42:20.326 30995-30995/com.example.apollographql.sample E/GitHuntFeedActivity: Failed to parse http response com.apollographql.apollo.exception.ApolloParseException: Failed to parse http response at com.apollographql.apollo.internal.interceptor.ApolloParseInterceptor.parse(ApolloParseInterceptor.java:104) at com.apollographql.apollo.internal.interceptor.ApolloParseInterceptor.access$100(ApolloParseInterceptor.java:30) at com.apollographql.apollo.internal.interceptor.ApolloParseInterceptor$1.onResponse(ApolloParseInterceptor.java:64) at com.apollographql.apollo.internal.interceptor.ApolloServerInterceptor$1$1.onResponse(ApolloServerInterceptor.java:112) at okhttp3.RealCall$AsyncCall.execute(RealCall.java:141) at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) at java.lang.Thread.run(Thread.java:761) Caused by: java.io.EOFException: End of input at com.apollographql.apollo.internal.json.BufferedSourceJsonReader.nextNonWhitespace(BufferedSourceJsonReader.java:945) at com.apollographql.apollo.internal.json.BufferedSourceJsonReader.doPeek(BufferedSourceJsonReader.java:332) at com.apollographql.apollo.internal.json.BufferedSourceJsonReader.beginObject(BufferedSourceJsonReader.java:169) at com.apollographql.apollo.internal.interceptor.HttpResponseBodyParser.parse(HttpResponseBodyParser.java:42) at com.apollographql.apollo.internal.interceptor.ApolloParseInterceptor.parse(ApolloParseInterceptor.java:93) at com.apollographql.apollo.internal.interceptor.ApolloParseInterceptor.access$100(ApolloParseInterceptor.java:30)聽 at com.apollographql.apollo.internal.interceptor.ApolloParseInterceptor$1.onResponse(ApolloParseInterceptor.java:64)聽 at com.apollographql.apollo.internal.interceptor.ApolloServerInterceptor$1$1.onResponse(ApolloServerInterceptor.java:112)聽 at okhttp3.RealCall$AsyncCall.execute(RealCall.java:141)聽 at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)聽 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)聽 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)聽 at java.lang.Thread.run(Thread.java:761)聽

Maybe the logging interceptor is reading from the same buffer as the ApolloParseInterceptor, then the parse interceptor cannot read the data from the previously used response buffer.

Runtime Bug

Most helpful comment

I believe you should change this new OkHttpClient.Builder() .addInterceptor(interceptor) .build() to new OkHttpClient.Builder() .addNetworkInterceptor(interceptor) .build().

But we saw this issue in the past, we will take a look meantime.

All 5 comments

I believe you should change this new OkHttpClient.Builder() .addInterceptor(interceptor) .build() to new OkHttpClient.Builder() .addNetworkInterceptor(interceptor) .build().

But we saw this issue in the past, we will take a look meantime.

My app will not work correctly if I switch to 'addNetworkInterceptor' from 'addInterceptor'. I need to support graphql and use this 'addInterceptor'. Is there any other work around?
-Edit- I think I figured out my issue, and can still use 'addInterceptor'.

@fluxxion82 what solution did you use? Appreciate your response. Thanks!

@akosijiji sorry I didn't see your comment until now. So I have custom interceptor to be able to use different urls and headers for rest and graphql clients. I was still able to use the 'addInterceptor' method...I have to explicitly set the url and header on the interceptor before every network call, which I probably should have been doing before using apollo but don't remember having issues. I have a logging interceptor that I use with the 'addNetworkInterceptor' method now though.

Closing as very low priority.

Was this page helpful?
0 / 5 - 0 ratings