SweetzpotAS / StravaZpot-Android

A fluent API to integrate with Strava on Android apps
70 stars 36 forks source link

Upload API: com.google.gson.stream.MalformedJsonException #14

Closed starryalley closed 6 years ago

starryalley commented 6 years ago

Hi,

I plan to use the upload API for my app and I have made sure the returned token is working correctly by using curl to upload the same GPX file.

I am getting MalformedJsonException with this call to UploadAPI:

UploadStatus uploadStatus = uploadAPI.uploadFile(new File(gpxDir, filename))
                    .withDataType(DataType.GPX)
                    .withActivityType(UploadActivityType.RIDE) 
                    .withName("test gpx")
                    .withDescription("")
                    .isPrivate(false)
                    .hasTrainer(false)
                    .isCommute(false)
                    .withExternalID(filename)
                    .execute();

Exception stack:

java.lang.RuntimeException: An error occurred while executing doInBackground()
    at android.os.AsyncTask$3.done(AsyncTask.java:353)
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
    at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
    at java.util.concurrent.FutureTask.run(FutureTask.java:271)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
    at java.lang.Thread.run(Thread.java:764)
Caused by: com.sweetzpot.stravazpot.common.api.exception.StravaAPIException: A network error happened contacting Strava API
    at com.sweetzpot.stravazpot.common.api.StravaAPI.execute(StravaAPI.java:28)
    at com.sweetzpot.stravazpot.upload.request.UploadFileRequest.execute(UploadFileRequest.java:91)
    at idv.markkuo.ambitsync.MoveInfoActivity$StravaUploadAsyncTask.doInBackground(MoveInfoActivity.java:243)
    at idv.markkuo.ambitsync.MoveInfoActivity$StravaUploadAsyncTask.doInBackground(MoveInfoActivity.java:223)
    at android.os.AsyncTask$2.call(AsyncTask.java:333)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    ... 4 more
Caused by: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path $
    at com.google.gson.stream.JsonReader.syntaxError(JsonReader.java:1559)
    at com.google.gson.stream.JsonReader.checkLenient(JsonReader.java:1401)
    at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:593)
    at com.google.gson.stream.JsonReader.peek(JsonReader.java:425)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:205)
    at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:37)
    at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:25)
    at retrofit2.ServiceMethod.toResponse(ServiceMethod.java:117)
    at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:211)
    at retrofit2.OkHttpCall.execute(OkHttpCall.java:174)
    at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall.execute(ExecutorCallAdapterFactory.java:89)
    at com.sweetzpot.stravazpot.common.api.StravaAPI.execute(StravaAPI.java:26)
    ... 9 more

I am new to Retrofit API. I can't seem to enable the logging so I can't check what's returning from strava. Could you give me a hint? Thanks so much.

truizlop commented 6 years ago

Are you enabling debug on the StravaConfig?

StravaConfig config = StravaConfig.withToken(TOKEN)
                                  .debug()
                                  .build();

That may help to visualize what is being serialized incorrectly to JSON. Also, make sure the path to the GPX file is correct.

starryalley commented 6 years ago

Thanks for the quick answer. I found out that I am using the wrong StravaConfig instance to call the API. Now it is working perfectly fine! I'll close this issue soon but one more question about the UploadAPI.

According to Strava document, only "data_type" and "file" is required when uploading. Is there any design reason why we should fill in all fields (such as name, description, etc) before we can execute() it?

Thanks again for the support.

truizlop commented 6 years ago

No, the Upload API lets you omit those parameters which are not required by Strava. You simply omit the call to the method and it will check internally:

UploadStatus uploadStatus = uploadAPI.uploadFile(new File(gpxDir, filename))
                    .withDataType(DataType.GPX)
                    .execute();
starryalley commented 6 years ago

I might have missed something but I got this exception if I only call withDataType():

upload failed with exception:java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.sweetzpot.stravazpot.upload.model.UploadActivityType.toString()' on a null object reference
truizlop commented 6 years ago

I'm sorry, you are right. All parameters are required at this point. According to Strava docs, it does not state that they are optional though, so you will need to set appropriate values to all the parameters.

starryalley commented 6 years ago

Thanks for confirmation. I did read the code and found out so. Didn't know if it's design choice or not since I am only using the upload API part. Thanks again for this awesome library!

truizlop commented 6 years ago

Thank you for using it!