Skip to content

App Crashed on manual retrying with: java.lang.IllegalStateException: You have already called startUpload() on this Upload request instance once and you cannot call it multiple times. Check your code. #672

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
1 task done
PavlosTze opened this issue Jan 15, 2025 · 7 comments · Fixed by #673

Comments

@PavlosTze
Copy link
Contributor

Describe the bug
I followed your guide on Advanced topics mentioning:

So, what I suggest you to do is to keep a reference to the uploadID and the upload request object somewhere in your code, so you can trigger upload again by calling the startUpload method on the request object when certain conditions (e.g. server is reachable again) are met.

But I got a crash with a following message:
java.lang.IllegalStateException: You have already called startUpload() on this Upload request instance once and you cannot call it multiple times. Check your code.

To Reproduce
Steps to reproduce the behavior:

  1. Create a failed request (e.g. close the internet before uploading)
  2. Call startUpload again on this request
  3. See error

Expected behavior
To retry properly.

OS and Lib versions (please complete the following information):

  • Android Upload Service version: 4.9.3
  • Android version and API version: Android 14
  • HTTP stack: OkHttpStack

Request code:

            val request = repository.getUploadIdRequest(it)
            request?.setUploadID(it)
            request?.startUpload()

Where have you added the request code?

  • Activity

Debug Log:

java.lang.IllegalStateException: You have already called startUpload() on this Upload request instance once and you cannot call it multiple times. Check your code.
                                                                                                    	at net.gotev.uploadservice.UploadRequest.startUpload(UploadRequest.kt:68)
                                                                                                    	at com.weatherxm.usecases.DevicePhotoUseCaseImpl.retryUpload(DevicePhotoUseCase.kt:73)
                                                                                                    	at com.weatherxm.ui.devicesettings.BaseDeviceSettingsViewModel.retryPhotoUpload(BaseDeviceSettingsViewModel.kt:218)
                                                                                                    	at com.weatherxm.ui.devicesettings.wifi.DeviceSettingsWifiActivity.onPhotos$lambda$19(DeviceSettingsWifiActivity.kt:201)
                                                                                                    	at com.weatherxm.ui.devicesettings.wifi.DeviceSettingsWifiActivity.$r8$lambda$kSy6cgZ6VJazm_Axn4tj6VuaazI(Unknown Source:0)
                                                                                                    	at com.weatherxm.ui.devicesettings.wifi.DeviceSettingsWifiActivity$$ExternalSyntheticLambda19.invoke(D8$$SyntheticClass:0)
                                                                                                    	at com.weatherxm.ui.devicesettings.DevicePhotosView.setOnClickListener$lambda$4(DevicePhotosView.kt:87)
                                                                                                    	at com.weatherxm.ui.devicesettings.DevicePhotosView.$r8$lambda$rQcjTDg3INNsRE1dQ_yDaZrhtwk(Unknown Source:0)
                                                                                                    	at com.weatherxm.ui.devicesettings.DevicePhotosView$$ExternalSyntheticLambda5.onClick(D8$$SyntheticClass:0)
                                                                                                    	at android.view.View.performClick(View.java:8047)
                                                                                                    	at android.widget.TextView.performClick(TextView.java:17792)
                                                                                                    	at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1218)
                                                                                                    	at android.view.View.performClickInternal(View.java:8024)
                                                                                                    	at android.view.View.-$$Nest$mperformClickInternal(Unknown Source:0)
                                                                                                    	at android.view.View$PerformClick.run(View.java:31890)
                                                                                                    	at android.os.Handler.handleCallback(Handler.java:958)
                                                                                                    	at android.os.Handler.dispatchMessage(Handler.java:99)
                                                                                                    	at android.os.Looper.loopOnce(Looper.java:230)
                                                                                                    	at android.os.Looper.loop(Looper.java:319)
                                                                                                    	at android.app.ActivityThread.main(ActivityThread.java:8919)
                                                                                                    	at java.lang.reflect.Method.invoke(Native Method)
                                                                                                    	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:578)
                                                                                                    	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)

Other info:
Project

@gotev
Copy link
Owner

gotev commented Jan 15, 2025

@PavlosTze having also an automatic test for this, please check your app's lifecycle where you are starting the upload, this exception is thrown when you are starting the same upload twice. What is exactly "Manual retrying"? You should use the retry policy mechanism of the library instead.

@PavlosTze
Copy link
Contributor Author

PavlosTze commented Jan 16, 2025

@PavlosTze having also an automatic test for this, please check your app's lifecycle where you are starting the upload, this exception is thrown when you are starting the same upload twice. What is exactly "Manual retrying"? You should use the retry policy mechanism of the library instead.

We use the automatic retry policy, but we also have a "Retry" button when the upload fails, which the user can click, and based in your guide I posted above, I save the uploadId and the MultipartUploadRequest and I run startUpload again when that retry button gets clicked.

Isn't it the correct solution?

@gotev
Copy link
Owner

gotev commented Jan 16, 2025

That guide is really old and maybe needs a refresh. It's been written before the persistent uploads feature and it covers only a bare minimum simple example. In your case you are attempting to retry an upload which is still in the execution phase and so the exception is correct. You can check the running tasks using the management APIs before attempting to start the upload.

@PavlosTze
Copy link
Contributor Author

PavlosTze commented Jan 17, 2025

That guide is really old and maybe needs a refresh. It's been written before the persistent uploads feature and it covers only a bare minimum simple example. In your case you are attempting to retry an upload which is still in the execution phase and so the exception is correct. You can check the running tasks using the management APIs before attempting to start the upload.

I just tried again to debug it with the management APIs:
UploadService.taskList returns an empty list (which means no tasks are running). My upload tasks fail with an exception and I retry afterwards to call startUpload again, and it crashes.

Even the onCompleted on class GlobalUploadObserverService() : RequestObserverDelegate gets called.

I think the problem is that on UploadRequest, the started variable becomes started = true on startUpload, and stays in that state. Whereas in my opinion in case of an error or a success it should go back to the false state as that means that the service has stoped.

@gotev
Copy link
Owner

gotev commented Jan 17, 2025

Actually it could be safe to completely remove the "started" private property and relative checks and rely on the task list checks which should be sufficient. You are welcome to make a PR.

@PavlosTze
Copy link
Contributor Author

PavlosTze commented Jan 17, 2025

Actually it could be safe to completely remove the "started" private property and relative checks and rely on the task list checks which should be sufficient. You are welcome to make a PR.

Ready. If that's OK, could you please release a new version as we need this feature in our project?

@gotev
Copy link
Owner

gotev commented Jan 18, 2025

Released fix in 4.9.4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants