From b01c668f49e1bd5bd9ff08771ce6a2d323cfadb5 Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Tue, 16 Jun 2026 13:42:36 +0200 Subject: [PATCH 1/3] fix(file-upload-worker): better error handling Signed-off-by: alperozturk96 # Conflicts: # gradle/libs.versions.toml --- .../client/jobs/upload/FileUploadWorker.kt | 50 +++++++++++++++---- gradle/verification-metadata.xml | 8 +++ 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadWorker.kt b/app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadWorker.kt index a23d3590eda9..726dfa792279 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadWorker.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadWorker.kt @@ -26,6 +26,7 @@ import com.nextcloud.client.network.ConnectivityService import com.nextcloud.client.preferences.AppPreferences import com.nextcloud.utils.ForegroundServiceHelper import com.nextcloud.utils.extensions.getPercent +import com.nextcloud.utils.extensions.isNonRetryable import com.nextcloud.utils.extensions.toFile import com.owncloud.android.R import com.owncloud.android.datamodel.ForegroundServiceType @@ -34,6 +35,7 @@ import com.owncloud.android.datamodel.SyncedFolderProvider import com.owncloud.android.datamodel.ThumbnailsCacheManager import com.owncloud.android.datamodel.UploadsStorageManager import com.owncloud.android.db.OCUpload +import com.owncloud.android.db.UploadResult import com.owncloud.android.lib.common.OwnCloudAccount import com.owncloud.android.lib.common.OwnCloudClient import com.owncloud.android.lib.common.OwnCloudClientManagerFactory @@ -204,6 +206,18 @@ class FileUploadWorker( .setSilent(true) .build() + private enum class UploadFilesResult { + Success, + Error, + Retry; + + fun toWorkerResult(): Result = when (this) { + Success -> Result.success() + Error -> Result.failure() + Retry -> Result.retry() + } + } + @Suppress("ReturnCount", "LongMethod", "DEPRECATION") private suspend fun uploadFiles(): Result = withContext(Dispatchers.IO) { val accountName = inputData.getString(ACCOUNT) @@ -246,6 +260,7 @@ class FileUploadWorker( val client = OwnCloudClientManagerFactory.getDefaultSingleton().getClientFor(ocAccount, context) val syncFolderHelper = SyncFolderHelper(context) val syncedFolders = syncedFolderProvider.syncedFolders + var uploadFilesResult = UploadFilesResult.Success for ((index, upload) in uploads.withIndex()) { ensureActive() @@ -288,20 +303,32 @@ class FileUploadWorker( ) val result = withContext(Dispatchers.IO) { - upload(upload, operation, user, client) + upload(operation, user, client) } activeOperations.remove(upload.uploadId) + // check quota first if (result.code == ResultCode.QUOTA_EXCEEDED) { Log_OC.w(TAG, "Quota exceeded, stopping uploads") notificationManager.showQuotaExceedNotification(operation) break } + // check upload result for worker + val uploadResult = UploadResult.fromOperationResult(result) + if (!result.isSuccess) { + Log_OC.e(TAG, "upload failed for ${upload.remotePath}: ${result.code}") + uploadFilesResult = if (uploadResult.isNonRetryable()) { + UploadFilesResult.Error + } else { + UploadFilesResult.Retry + } + } + sendUploadFinishEvent(totalUploadSize, currentUploadIndex, operation, result) } - return@withContext Result.success() + return@withContext uploadFilesResult.toWorkerResult() } @Suppress("ReturnCount") @@ -356,21 +383,24 @@ class FileUploadWorker( @Suppress("TooGenericExceptionCaught", "DEPRECATION") private suspend fun upload( - upload: OCUpload, operation: UploadFileOperation, user: User, client: OwnCloudClient ): RemoteOperationResult = withContext(Dispatchers.IO) { - lateinit var result: RemoteOperationResult + var result: RemoteOperationResult try { val storageManager = operation.storageManager - result = operation.execute(client) - val task = ThumbnailsCacheManager.ThumbnailGenerationTask(storageManager, user) - val file = File(operation.originalStoragePath) - val remoteId: String? = operation.file.remoteId - task.execute(ThumbnailsCacheManager.ThumbnailGenerationTaskObject(file, remoteId)) fileUploadEventBroadcaster.sendUploadStarted(operation, context) + result = operation.execute(client) + + // only generate a thumbnail if the upload actually succeeded + if (result.isSuccess) { + val task = ThumbnailsCacheManager.ThumbnailGenerationTask(storageManager, user) + val file = File(operation.originalStoragePath) + val remoteId: String? = operation.file.remoteId + task.execute(ThumbnailsCacheManager.ThumbnailGenerationTaskObject(file, remoteId)) + } } catch (e: Exception) { Log_OC.e(TAG, "Error uploading", e) result = RemoteOperationResult(e) @@ -405,7 +435,7 @@ class FileUploadWorker( private var lastUpdateTime = 0L /** - * Receives from [com.owncloud.android.operations.UploadFileOperation.normalUpload] + * Receives from [UploadFileOperation.normalUpload] */ @Suppress("MagicNumber") override fun onTransferProgress( diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 70e29c1a3e08..2a954112fae5 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -21389,6 +21389,14 @@ + + + + + + + + From a441fedb5ce80bbe4c77167f40f21921baed9c20 Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Tue, 16 Jun 2026 13:47:41 +0200 Subject: [PATCH 2/3] fix(file-upload-worker): better error handling Signed-off-by: alperozturk96 --- .../com/nextcloud/client/jobs/upload/FileUploadWorker.kt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadWorker.kt b/app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadWorker.kt index 726dfa792279..65bb0308e537 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadWorker.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadWorker.kt @@ -318,10 +318,11 @@ class FileUploadWorker( val uploadResult = UploadResult.fromOperationResult(result) if (!result.isSuccess) { Log_OC.e(TAG, "upload failed for ${upload.remotePath}: ${result.code}") - uploadFilesResult = if (uploadResult.isNonRetryable()) { - UploadFilesResult.Error - } else { - UploadFilesResult.Retry + if (uploadResult.isNonRetryable()) { + uploadFilesResult = UploadFilesResult.Error + } else if (uploadFilesResult != UploadFilesResult.Error) { + // only set retry if any other not failed before + uploadFilesResult = UploadFilesResult.Retry } } From a70d984f64c978c060258d1e935e33328afc796c Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Fri, 19 Jun 2026 12:27:43 +0200 Subject: [PATCH 3/3] wip Signed-off-by: alperozturk96 --- gradle/libs.versions.toml | 2 +- gradle/verification-metadata.xml | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d81ffb96fe70..7a18395f5ffd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,7 +5,7 @@ androidCommonLibraryVersion = "0.33.2" androidGifDrawableVersion = "1.2.31" androidImageCropperVersion = "4.7.0" -androidLibraryVersion ="11c1f0d68c55d7537e2ebae5da40d13b1b93c729" +androidLibraryVersion ="1bdcdd40eb" androidOpensslVersion = "3.5.6" androidPluginVersion = "9.2.1" androidsvgVersion = "1.4" diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 2a954112fae5..8d5743a71684 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -20941,6 +20941,14 @@ + + + + + + + +