Search code examples
apollo-clientgraphql-javaapollo-android

com.apollographql.apollo.exception.ApolloParseException: Failed to parse http response


I am getting the "Failed to parse http response" exception for a particular Profile query. It seems data is read successfully with a 200 OK response as seen from the logs but the control goes to onFailure of the query.

  1. Before this query, the program runs mutation successfully without any issues.
  2. Only the Profile query issues the exception.
  3. And this query runs fine at the server also.

Logs:

2019-09-23 16:57:45.431 27729-28889/com.sed.RP D/OkHttp: --> POST https://rf-xxx-xxxxxxxxx.com/
2019-09-23 16:57:45.432 27729-28889/com.sed.RP D/OkHttp: Content-Length: 329
2019-09-23 16:57:45.432 27729-28889/com.sed.RP D/OkHttp: Content-Type: application/json
2019-09-23 16:57:45.432 27729-28889/com.sed.RP D/OkHttp: Accept: application/json
2019-09-23 16:57:45.432 27729-28889/com.sed.RP D/OkHttp: X-APOLLO-OPERATION-ID: 7572eb1080830d1b4c285bb96f09ac5ad2417ab45fcb701d5d9608593f95874c
2019-09-23 16:57:45.432 27729-28889/com.sed.RP D/OkHttp: X-APOLLO-OPERATION-NAME: profile
2019-09-23 16:57:45.433 27729-28889/com.sed.RP D/OkHttp: Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1ZDdmY2E4NmVmMGFiMzAwMjRjNTk3NWIiLCJyb2xlIjoiVEVBQ0hFUiIsImVtYWlsIjoiaXRhYmR1bGxhaC5zZWRAZ21haWwuY29tIiwibW9iaWxlIjoiMDEyMzQ1Njc4OSIsImNvdW50cnlDb2RlIjoiS1NBIiwiaXNzdWVkQXQiOiIyMDE5LTA5LTIzVDExOjI3OjQ1LjA2NFoiLCJpYXQiOjE1NjkyMzgwNjUsImV4cCI6MTU2OTg0Mjg2NX0.3LNNSPenLuMGmOxdD_9KKoqrKo0eyPkWe0qx8MZjZME
2019-09-23 16:57:45.433 27729-28889/com.sed.RP D/OkHttp: X-APOLLO-CACHE-KEY: dbde9fb84c5eda4a362f8db542fef516
2019-09-23 16:57:45.433 27729-28889/com.sed.RP D/OkHttp: X-APOLLO-CACHE-FETCH-STRATEGY: NETWORK_ONLY
2019-09-23 16:57:45.433 27729-28889/com.sed.RP D/OkHttp: X-APOLLO-EXPIRE-TIMEOUT: 0
2019-09-23 16:57:45.433 27729-28889/com.sed.RP D/OkHttp: X-APOLLO-EXPIRE-AFTER-READ: false
2019-09-23 16:57:45.433 27729-28889/com.sed.RP D/OkHttp: X-APOLLO-PREFETCH: false
2019-09-23 16:57:45.434 27729-28889/com.sed.RP D/OkHttp: X-APOLLO-CACHE-DO-NOT-STORE: false
2019-09-23 16:57:45.435 27729-28889/com.sed.RP D/OkHttp: {"operationName":"profile","variables":{},"query":"query profile($_id:ID) {  profile(_id:$_id) {    __typename    _id    fullName    firstName    lastName    email    classDetails {      __typename      _id      className      section      subjectName    }    academicYear {      __typename      startYear      endYear    }  }}"}
2019-09-23 16:57:45.435 27729-28889/com.sed.RP D/OkHttp: --> END POST (329-byte body)
2019-09-23 16:57:46.960 27729-28889/com.sed.RP D/OkHttp: <-- 200 OK https://rf-xxx-xxxxxxxxxxx/ (1524ms)
2019-09-23 16:57:46.960 27729-28889/com.sed.RP D/OkHttp: Server: Cowboy
2019-09-23 16:57:46.960 27729-28889/com.sed.RP D/OkHttp: Connection: keep-alive
2019-09-23 16:57:46.960 27729-28889/com.sed.RP D/OkHttp: X-Powered-By: Express
2019-09-23 16:57:46.960 27729-28889/com.sed.RP D/OkHttp: Access-Control-Allow-Origin: *
2019-09-23 16:57:46.961 27729-28889/com.sed.RP D/OkHttp: Content-Type: application/json
2019-09-23 16:57:46.961 27729-28889/com.sed.RP D/OkHttp: Content-Length: 937
2019-09-23 16:57:46.961 27729-28889/com.sed.RP D/OkHttp: Date: Mon, 23 Sep 2019 11:27:46 GMT
2019-09-23 16:57:46.961 27729-28889/com.sed.RP D/OkHttp: Via: 1.1 vegur
2019-09-23 16:57:46.962 27729-28889/com.sed.RP D/OkHttp: {"data":{"profile":{"__typename":"User","_id":"5d7fca86ef0ab30024c5975b","fullName":"Mohamed Abdullah K","firstName":"Mohamed Abdullah","lastName":"K","email":"[email protected]","classDetails":[{"__typename":"ClassDetails","_id":"5d8740e72c34b80024a8e31d","className":"tula","section":"2014","subjectName":"embedded"},{"__typename":"ClassDetails","_id":"5d8748ac2c34b80024a8e337","className":"tula","section":"2014","subjectName":"embedded"},{"__typename":"ClassDetails","_id":"5d8748d92c34b80024a8e338","className":"miah","section":"2018","subjectName":"maths"},{"__typename":"ClassDetails","_id":"5d87537e2c34b80024a8e33a","className":"Miah","section":"Tula","subjectName":"First"},{"__typename":"ClassDetails","_id":"5d88656336c2360024d0deb8","className":"IT","section":"2017","subjectName":"Arabic"}],"academicYear":{"__typename":"AcademicYear","startYear":"2012-01-01T00:00:00.000Z","endYear":"2013-01-01T00:00:00.000Z"}}}}
2019-09-23 16:57:46.962 27729-28889/com.sed.RP D/OkHttp: <-- END HTTP (937-byte body)

My query:

RequestHeaders requestHeaders = RequestHeaders.builder().addHeader(LoginActivity.AUTHORIZATION, bearerTokenTest).build();
        ProfileQuery profileQuery = ProfileQuery.builder().build();
        ApiClient.getMyApolloClient().query(profileQuery)
                .requestHeaders(requestHeaders)
                .enqueue(new ApolloCall.Callback<ProfileQuery.Data>() {
                    @Override
                    public void onResponse(@NotNull Response<ProfileQuery.Data> response) {

                        if (response.data() != null) {
                            Timber.e("onResponse: %s", response.data().profile()._id());
                            //processResponse(response);
                        }
                        if (!response.errors().isEmpty())
                            Timber.e("onResponse error: %s", response.errors().get(0).message());
                    }

                    @Override
                    public void onFailure(@NotNull ApolloException e) {
                        Timber.e("onFailure: %s", e.toString());
                        //processFailure();
                    }
                });

Graphql:

query profile($_id:ID){
    profile(_id:$_id){
        _id
        fullName
        firstName
        lastName
        email
        classDetails{
            _id
            className
            section
            subjectName
        }
        academicYear{
            startYear
            endYear
        }
    }
}

Apollo-client:


public class ApiClient {

    private static final String BASE_URL = "https://rf-xxxx.x.com";
    public static ApolloClient apolloClient;

    public static ApolloClient getMyApolloClient() {
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.level(HttpLoggingInterceptor.Level.BODY);

        OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();

        apolloClient = ApolloClient.builder()
                .serverUrl(BASE_URL)
                .okHttpClient(client)
                .build();
        return apolloClient;
    }

}

gradle:

buildscript {

    repositories {
        google()
        jcenter()
        maven { url "https://jitpack.io" } //comment if necessary
        maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.5.0'
        classpath 'com.apollographql.apollo:apollo-gradle-plugin:1.1.3'
        classpath 'com.apollographql.apollo:apollo-gradle-plugin:1.2.0-SNAPSHOT'


        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files

    }
}

Thanks for any suggestions.


Solution

  • It is the issue of missing "Custom DATE Type Adapter" in the Apollo Client Builder as found from the stacktrace.

    java.lang.IllegalArgumentException: Can't map GraphQL type: Date to: class java.lang.Object. Did you forget to add custom type adapter?
        at com.apollographql.apollo.response.ScalarTypeAdapters.adapterFor(ScalarTypeAdapters.java:30)
        at com.apollographql.apollo.internal.response.RealResponseReader.readCustomType(RealResponseReader.java:193)
    
    

    I have added Custom Type Adapter as below to the Apollo Client Builder and it works fine now.

    
    public static ApolloClient getMyApolloClient() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sss'Z'", Locale.US);
        CustomTypeAdapter dateCustomTypeAdapter = new CustomTypeAdapter<Date>() {
            @Override
            public Date decode(CustomTypeValue value) {
                try {
                    return dateFormat.parse(value.value.toString());
                } catch (ParseException e) {
                    throw new RuntimeException(e);
                }
            }
    
            @Override
            public CustomTypeValue encode(Date value) {
                return new CustomTypeValue.GraphQLString(dateFormat.format(value));
            }
        };
    
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.level(HttpLoggingInterceptor.Level.BODY);
    
        OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
    
        apolloClient = ApolloClient.builder()
                .serverUrl(BASE_URL)
                .okHttpClient(client)
                .addCustomTypeAdapter(CustomType.DATE, dateCustomTypeAdapter)
                .build();
        return apolloClient;
    }