google / java-photoslibrary

Java client library for the Google Photos Library API
http://developers.google.com/photos
Apache License 2.0
107 stars 64 forks source link

Uploading a zero-length NEF file results in "com.google.api.gax.rpc.ApiException: java.lang.IllegalArgumentException: The upload was completed but failed to finalize or get the result" #29

Closed ylexus closed 2 years ago

ylexus commented 4 years ago

Using google-photos-library-client 1.4.0. The following code:

            com.google.photos.library.v1.PhotosLibraryClient theClient = ...
            try (RandomAccessFile randomAccessFile = new RandomAccessFile(file.toFile(), "r")) {
                UploadMediaItemRequest uploadRequest = UploadMediaItemRequest.newBuilder()
                        .setFileName(fileName)
                        .setDataFile(randomAccessFile)
                        .build();
                uploadResponse = theClient.uploadMediaItem(uploadRequest);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            uploadResponse.getError().ifPresent(error -> {throw new RuntimeException("Failed uploading " + file, error.getCause());});

if passed a zero-length file (in my the file name was DSC_4791.NEF, if that makes any difference), results in

Caused by: java.lang.RuntimeException: Failed uploading /.../DSC_4791.NEF
    at net.yudichev.jiotty.connector.google.photos.GooglePhotosClientImpl.lambda$null$1(GooglePhotosClientImpl.java:71) ~[jiotty-connector-google-photos-1.4.1.jar:?]
    at java.util.Optional.ifPresent(Optional.java:176) ~[?:?]
    at net.yudichev.jiotty.connector.google.photos.GooglePhotosClientImpl.lambda$null$4(GooglePhotosClientImpl.java:71) ~[jiotty-connector-google-photos-1.4.1.jar:?]
    at net.yudichev.jiotty.common.inject.BaseLifecycleComponent.lambda$whenStartedAndNotLifecycling$5(BaseLifecycleComponent.java:60) ~[jiotty-common-1.4.1.jar:?]
    at net.yudichev.jiotty.common.lang.Locks.inLock(Locks.java:22) ~[jiotty-common-1.4.1.jar:?]
    at net.yudichev.jiotty.common.inject.BaseLifecycleComponent.whenNotLifecycling(BaseLifecycleComponent.java:54) ~[jiotty-common-1.4.1.jar:?]
    at net.yudichev.jiotty.common.inject.BaseLifecycleComponent.whenStartedAndNotLifecycling(BaseLifecycleComponent.java:58) ~[jiotty-common-1.4.1.jar:?]
    at net.yudichev.jiotty.connector.google.photos.GooglePhotosClientImpl.lambda$uploadMediaItem$5(GooglePhotosClientImpl.java:58) ~[jiotty-connector-google-photos-1.4.1.jar:?]
    at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1771) ~[?:?]
    ... 3 more
Caused by: com.google.api.gax.rpc.ApiException: java.lang.IllegalArgumentException: The upload was completed but failed to finalize or get the result.
    at com.google.photos.library.v1.upload.PhotosLibraryUploadExceptionMappingFn.apply(PhotosLibraryUploadExceptionMappingFn.java:48) ~[google-photos-library-client-1.4.0.jar:1.4.0]
    at com.google.photos.library.v1.upload.PhotosLibraryUploadExceptionMappingFn.apply(PhotosLibraryUploadExceptionMappingFn.java:29) ~[google-photos-library-client-1.4.0.jar:1.4.0]
    at com.google.api.core.ApiFutures$GaxFunctionToGuavaFunction.apply(ApiFutures.java:204) ~[api-common-1.8.1.jar:?]
    at com.google.common.util.concurrent.AbstractCatchingFuture$CatchingFuture.doFallback(AbstractCatchingFuture.java:223) ~[guava-28.2-jre.jar:?]
    at com.google.common.util.concurrent.AbstractCatchingFuture$CatchingFuture.doFallback(AbstractCatchingFuture.java:211) ~[guava-28.2-jre.jar:?]
    at com.google.common.util.concurrent.AbstractCatchingFuture.run(AbstractCatchingFuture.java:124) ~[guava-28.2-jre.jar:?]
    at com.google.common.util.concurrent.DirectExecutor.execute(DirectExecutor.java:30) ~[guava-28.2-jre.jar:?]
    at com.google.common.util.concurrent.ExecutionList.executeListener(ExecutionList.java:141) ~[guava-28.2-jre.jar:?]
    at com.google.common.util.concurrent.ExecutionList.execute(ExecutionList.java:130) ~[guava-28.2-jre.jar:?]
    at com.google.common.util.concurrent.ListenableFutureTask.done(ListenableFutureTask.java:86) ~[guava-28.2-jre.jar:?]
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:381) ~[?:?]
    at java.util.concurrent.FutureTask.setException(FutureTask.java:250) ~[?:?]
    at java.util.concurrent.FutureTask.run(FutureTask.java:269) ~[?:?]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) ~[?:?]
    at java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[?:?]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) ~[?:?]
    ... 3 more
Caused by: java.lang.IllegalArgumentException: The upload was completed but failed to finalize or get the result.
    at com.google.photos.library.v1.upload.PhotosLibraryUploadCallable.buildUploadMediaItemResponse(PhotosLibraryUploadCallable.java:303) ~[google-photos-library-client-1.4.0.jar:1.4.0]
    at com.google.photos.library.v1.upload.PhotosLibraryUploadCallable.call(PhotosLibraryUploadCallable.java:183) ~[google-photos-library-client-1.4.0.jar:1.4.0]
    at com.google.photos.library.v1.upload.PhotosLibraryUploadCallable.call(PhotosLibraryUploadCallable.java:45) ~[google-photos-library-client-1.4.0.jar:1.4.0]
    at java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[?:?]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) ~[?:?]
    at java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[?:?]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) ~[?:?]
    ... 3 more

The problem here is that the wrapping ApiException.isRetryable() is set to true, although this is a permanent non recoverable failure, so it's impossible for the client code to rely on this flag to determine whether to retry or not:

Screenshot 2020-03-28 at 13 01 32

The only workaround is to analyse the text of the exception and act on that, which is brittle.

Related to https://github.com/ylexus/jiotty-photos-uploader/issues/11.

jfschmakeit commented 2 years ago

I believe this should be fixed now as part of the recent changes to uploads that were part of release 1.7.0.

I'm closing this issue, but please reopen and let us know if you are still seeing this after upgrading to the latest version. Thanks!