3

I am trying to parse a String array using Retrofit and GSON which is returned from the API:

This is what the response normally looks like (CASE 1):

["Scan finished, scan information embedded in this object", "https://www.virustotal.com/url/297c349554bdc7e2f09a85be309f08cb2f16a9174068bd5bc6e298ed90a5eed9/analysis/1485313628/", 8, 64]

This is what the response looks like in a specific case (CASE 2):

["Scan request successfully queued, come back later for the report", "https://www.virustotal.com/url/d06ed0b4b29aab735ee7b85c5c0af98fd4d983edcc597afe60e4c4ac2e25ea08/analysis/1485847248/", null, null]

In this case (CASE 2), I am getting an error from Retrofit/GSON:

W/System.err: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 2 path $
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at com.google.gson.stream.JsonReader.beginArray(JsonReader.java:350)
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:80)
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61)
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:37)
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:25)
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at retrofit2.ServiceMethod.toResponse(ServiceMethod.java:117)
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:211)
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:106)
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at okhttp3.RealCall$AsyncCall.execute(RealCall.java:133)
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
01-31 13:42:41.922 15746-15746/com.ssrij.testapp W/System.err:     at java.lang.Thread.run(Thread.java:761)

I call the API like this:

Call<ArrayList<String>> scanResults = myAPI.getScanResults(id);
scanResults.enqueue(...)

and the array gets populated fine in the normal case (CASE 1), but in this case (CASE 2), it throws the error.

I think it's because of the null values. I tried using a custom type adapter but it didn't fix the issue, also setting serializeNulls() on GsonBuilder didn't fix the issue.

Does anyone know a solution?

EDIT: After some more debugging, it seems like the server is returning a string in CASE 2 instead of the String array for some reason. When I visit the link manually, I do see the string array, but for some reason the response is String.

9
  • Can you add the response model? The problem is there i think Commented Jan 31, 2017 at 8:18
  • @JasonBourne I call the API like this: Call<ArrayList<String>> scanResults = myAPI.getScanResults(id); and the arrayList gets populated fine in the normal case, but in the other case with null values, it throws that error Commented Jan 31, 2017 at 8:20
  • also add another case result where it throws error Commented Jan 31, 2017 at 8:34
  • That's the only case where it throws the error. There are only two cases. @Pravin Commented Jan 31, 2017 at 8:34
  • look github.com/square/retrofit/issues/1062 Commented Jan 31, 2017 at 8:43

1 Answer 1

2

"Expected BEGIN_ARRAY but was STRING" means that the character Gson is parsing is a ", but it expected a [ (since you're trying to parse a list). Since the input doesn't correspond to the expected input, Gson has to fail. From Gson's perspective the case 2 input isn't any different than the case 1 input (and if nulls were an issue, the error message would say something to that effect).

Since this input isn't trusted (it's coming from a third-party server?) you should add some error handling code around the parse call, in order to account for the possibility that the input is malformed. At a minimum logging the received input upon failure would immediately make it clear that you're not receiving the expected array.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.