diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveThumbnailUploadJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveThumbnailUploadJob.kt index 3daa062556..20ff33a4a4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveThumbnailUploadJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveThumbnailUploadJob.kt @@ -212,8 +212,16 @@ class ArchiveThumbnailUploadJob private constructor( } is NetworkResult.StatusCodeError -> { - Log.w(TAG, "Failed to get an upload spec with status code ${specResult.code}") - return Result.retry(defaultBackoff()) + return when (specResult.code) { + 429 -> { + Log.w(TAG, "Rate limited when getting upload spec.") + Result.retry(specResult.retryAfter()?.inWholeMilliseconds ?: defaultBackoff()) + } + else -> { + Log.w(TAG, "Failed to get an upload spec with status code ${specResult.code}") + Result.retry(defaultBackoff()) + } + } } } @@ -261,8 +269,16 @@ class ArchiveThumbnailUploadJob private constructor( } is NetworkResult.StatusCodeError -> { - Log.w(TAG, "Hit a status code error of ${result.code} when trying to archive thumbnail for $attachmentId") - Result.retry(defaultBackoff()) + when (result.code) { + 429 -> { + Log.w(TAG, "Rate limited when trying to archive thumbnail for $attachmentId") + Result.retry(result.retryAfter()?.inWholeMilliseconds ?: defaultBackoff()) + } + else -> { + Log.w(TAG, "Hit a status code error of ${result.code} when trying to archive thumbnail for $attachmentId") + Result.retry(defaultBackoff()) + } + } } is NetworkResult.ApplicationError -> Result.fatalFailure(RuntimeException(result.throwable)) diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/BackupMessagesJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/BackupMessagesJob.kt index 97ede2b2db..562a74a269 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/BackupMessagesJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/BackupMessagesJob.kt @@ -168,7 +168,12 @@ class BackupMessagesJob private constructor( val auth = when (val result = BackupRepository.getSvrBAuth()) { is NetworkResult.Success -> result.result is NetworkResult.NetworkError -> return Result.retry(defaultBackoff()).logW(TAG, "Network error when getting SVRB auth.", result.getCause(), true) - is NetworkResult.StatusCodeError -> return Result.retry(defaultBackoff()).logW(TAG, "Status code error when getting SVRB auth.", result.getCause(), true) + is NetworkResult.StatusCodeError -> { + return when (result.code) { + 429 -> Result.retry(result.retryAfter()?.inWholeMilliseconds ?: defaultBackoff()).logW(TAG, "Rate limited when getting SVRB auth.", result.getCause(), true) + else -> Result.retry(defaultBackoff()).logW(TAG, "Status code error when getting SVRB auth.", result.getCause(), true) + } + } is NetworkResult.ApplicationError -> throw result.throwable } @@ -183,7 +188,10 @@ class BackupMessagesJob private constructor( Log.i(TAG, "[svrb-restore] No backup data found, continuing.", true) null } else { - return Result.retry(defaultBackoff()).logW(TAG, "[svrb-restore] Status code error when getting remote forward secrecy metadata.", result.getCause(), true) + return when (result.code) { + 429 -> Result.retry(result.retryAfter()?.inWholeMilliseconds ?: defaultBackoff()).logW(TAG, "[svrb-restore] Rate limited when getting remote forward secrecy metadata.", result.getCause(), true) + else -> Result.retry(defaultBackoff()).logW(TAG, "[svrb-restore] Status code error when getting remote forward secrecy metadata.", result.getCause(), true) + } } } is NetworkResult.ApplicationError -> { @@ -311,6 +319,10 @@ class BackupMessagesJob private constructor( return Result.failure() } } + 429 -> { + Log.i(TAG, "Rate limited when getting upload spec.", result.getCause(), true) + return Result.retry(result.retryAfter()?.inWholeMilliseconds ?: defaultBackoff()) + } else -> { Log.i(TAG, "Status code failure", result.getCause(), true) return Result.retry(defaultBackoff()) @@ -359,14 +371,21 @@ class BackupMessagesJob private constructor( } is NetworkResult.StatusCodeError -> { - Log.i(TAG, "Status code failure", uploadResult.getCause(), true) when (uploadResult.code) { 400 -> { Log.w(TAG, "400 likely means bad resumable state. Resetting the upload spec before retrying.", true) resumableMessagesBackupUploadSpec = null + return Result.retry(defaultBackoff()) + } + 429 -> { + Log.w(TAG, "Rate limited when uploading backup file.", uploadResult.getCause(), true) + return Result.retry(uploadResult.retryAfter()?.inWholeMilliseconds ?: defaultBackoff()) + } + else -> { + Log.i(TAG, "Status code failure (${uploadResult.code})", uploadResult.getCause(), true) + return Result.retry(defaultBackoff()) } } - return Result.retry(defaultBackoff()) } is NetworkResult.ApplicationError -> throw uploadResult.throwable diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/BackupRefreshJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/BackupRefreshJob.kt index 40db1866d0..21a547d883 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/BackupRefreshJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/BackupRefreshJob.kt @@ -81,8 +81,20 @@ class BackupRefreshJob private constructor( SignalStore.backup.lastCheckInSnoozeMillis = 0 Result.success() } - else -> { - Log.w(TAG, "Failed to refresh backup with server.", result.getCause()) + is NetworkResult.NetworkError -> { + Log.w(TAG, "Network error when refreshing backup.", result.getCause()) + Result.retry(defaultBackoff()) + } + is NetworkResult.StatusCodeError -> { + Log.w(TAG, "Status code error (${result.code}) when refreshing backup.", result.getCause()) + if (result.code == 429) { + Result.retry(result.retryAfter()?.inWholeMilliseconds ?: defaultBackoff()) + } else { + Result.failure() + } + } + is NetworkResult.ApplicationError -> { + Log.w(TAG, "Application error when refreshing backup.", result.throwable) Result.failure() } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/CopyAttachmentToArchiveJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/CopyAttachmentToArchiveJob.kt index 181acf2864..94d0ea3735 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/CopyAttachmentToArchiveJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/CopyAttachmentToArchiveJob.kt @@ -202,6 +202,10 @@ class CopyAttachmentToArchiveJob private constructor(private val attachmentId: A Result.retry(defaultBackoff()) } + 429 -> { + Log.w(TAG, "[$attachmentId]$mediaIdLog Rate limit exceeded. Retrying.") + Result.retry(archiveResult.retryAfter()?.inWholeMilliseconds ?: defaultBackoff()) + } else -> { Log.w(TAG, "[$attachmentId]$mediaIdLog Got back a non-2xx status code: ${archiveResult.code}. Retrying.") Result.retry(defaultBackoff()) diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/UploadAttachmentToArchiveJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/UploadAttachmentToArchiveJob.kt index 72a9f373ad..8fe2a344d2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/UploadAttachmentToArchiveJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/UploadAttachmentToArchiveJob.kt @@ -364,10 +364,13 @@ class UploadAttachmentToArchiveJob private constructor( when (ArchiveMediaUploadFormStatusCodes.from(uploadSpec.code)) { ArchiveMediaUploadFormStatusCodes.BadArguments, ArchiveMediaUploadFormStatusCodes.InvalidPresentationOrSignature, - ArchiveMediaUploadFormStatusCodes.InsufficientPermissions, - ArchiveMediaUploadFormStatusCodes.RateLimited -> { + ArchiveMediaUploadFormStatusCodes.InsufficientPermissions -> { return null to Result.retry(defaultBackoff()) } + ArchiveMediaUploadFormStatusCodes.RateLimited -> { + Log.w(TAG, "[$attachmentId] Rate limited when getting upload form.") + return null to Result.retry(uploadSpec.retryAfter()?.inWholeMilliseconds ?: defaultBackoff()) + } ArchiveMediaUploadFormStatusCodes.Unknown -> { return null to Result.retry(defaultBackoff())