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.
"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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With