From c23a5a2cfcf121160dcd7537480985bfa37b8d48 Mon Sep 17 00:00:00 2001 From: Julian Raufelder Date: Tue, 6 Jul 2021 15:30:34 +0200 Subject: [PATCH] Handle further exceptions in a less generic way --- .../data/cloud/crypto/CryptoImplDecorator.kt | 7 +-- .../cloud/crypto/CryptoImplVaultFormat7.kt | 2 - .../okhttplogging/HttpLoggingInterceptor.kt | 2 +- .../org/cryptomator/data/cloud/s3/S3Impl.kt | 52 ++++++++----------- .../network/WebDavCompatibleHttpClient.kt | 3 +- .../googledrive/GoogleDriveClientFactory.kt | 16 +++--- .../cloud/DataSourceCapturingAnswer.kt | 3 +- 7 files changed, 36 insertions(+), 49 deletions(-) diff --git a/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoImplDecorator.kt b/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoImplDecorator.kt index 646099c0..8c9cbaf1 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoImplDecorator.kt +++ b/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoImplDecorator.kt @@ -420,8 +420,7 @@ abstract class CryptoImplDecorator( assertCryptoFileAlreadyExists(cryptoFile) } try { - data.open(context).use { stream -> - requireNotNull(stream) + data.open(context)?.use { stream -> requireNotNull(cryptoFile.size) val encryptedTmpFile = File.createTempFile(UUID.randomUUID().toString(), ".crypto", internalCache) try { @@ -444,12 +443,10 @@ abstract class CryptoImplDecorator( return writeFromTmpFile(data, cryptoFile, encryptedTmpFile, progressAware, replace) } } - } catch (e: Throwable) { - throw e } finally { encryptedTmpFile.delete() } - } + } ?: throw IllegalStateException("InputStream shouldn't be null") } catch (e: IOException) { throw FatalBackendException(e) } diff --git a/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoImplVaultFormat7.kt b/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoImplVaultFormat7.kt index 87698d10..bc085a87 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoImplVaultFormat7.kt +++ b/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoImplVaultFormat7.kt @@ -481,8 +481,6 @@ open class CryptoImplVaultFormat7 : CryptoImplDecorator { } ?: throw FatalBackendException("CloudFile size shouldn't be null") } } - } catch (e: Throwable) { - throw e } finally { encryptedTmpFile.delete() } diff --git a/data/src/main/java/org/cryptomator/data/cloud/okhttplogging/HttpLoggingInterceptor.kt b/data/src/main/java/org/cryptomator/data/cloud/okhttplogging/HttpLoggingInterceptor.kt index 558eb6f0..b388fbb8 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/okhttplogging/HttpLoggingInterceptor.kt +++ b/data/src/main/java/org/cryptomator/data/cloud/okhttplogging/HttpLoggingInterceptor.kt @@ -49,7 +49,7 @@ class HttpLoggingInterceptor(private val logger: Logger, private val context: Co private fun getResponseLoggingExceptions(request: Request, chain: Interceptor.Chain): Response { return try { chain.proceed(request) - } catch (e: Exception) { + } catch (e: IOException) { logger.log("<-- HTTP FAILED: $e") throw e } diff --git a/data/src/main/java/org/cryptomator/data/cloud/s3/S3Impl.kt b/data/src/main/java/org/cryptomator/data/cloud/s3/S3Impl.kt index fbd13777..a5ff3f28 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/s3/S3Impl.kt +++ b/data/src/main/java/org/cryptomator/data/cloud/s3/S3Impl.kt @@ -88,8 +88,6 @@ internal class S3Impl(context: Context, cloud: S3Cloud) { return false } throw FatalBackendException(e) - } catch (ex: Exception) { - throw handleApiError(ex, node.path) } } @@ -114,8 +112,8 @@ internal class S3Impl(context: Context, cloud: S3Cloud) { } } } - } catch (ex: Exception) { - throw handleApiError(ex, folder.path) + } catch (e: ErrorResponseException) { + throw handleApiError(e, folder.path) } } @@ -140,8 +138,8 @@ internal class S3Impl(context: Context, cloud: S3Cloud) { .build() client().putObject(putObjectArgs) - } catch (ex: Exception) { - throw handleApiError(ex, folder.path) + } catch (e: ErrorResponseException) { + throw handleApiError(e, folder.path) } return S3CloudNodeFactory.folder(parentFolder, folder.name) @@ -181,8 +179,8 @@ internal class S3Impl(context: Context, cloud: S3Cloud) { val copyObjectArgs = CopyObjectArgs.builder().bucket(cloud.s3Bucket()).`object`(targetKey).source(copySource).build() try { client().copyObject(copyObjectArgs) - } catch (ex: Exception) { - throw handleApiError(ex, source.path) + } catch (e: ErrorResponseException) { + throw handleApiError(e, source.path) } } @@ -191,8 +189,8 @@ internal class S3Impl(context: Context, cloud: S3Cloud) { for (result in client().removeObjects(removeObjectsArgs)) { try { result.get() - } catch (ex: Exception) { - throw handleApiError(ex, source.path) + } catch (e: ErrorResponseException) { + throw handleApiError(e, source.path) } } @@ -209,8 +207,8 @@ internal class S3Impl(context: Context, cloud: S3Cloud) { delete(source) val lastModified = result.headers().getDate("Last-Modified") return S3CloudNodeFactory.file(target.parent, target.name, source.size, lastModified) - } catch (ex: Exception) { - throw handleApiError(ex, source.path) + } catch (e: ErrorResponseException) { + throw handleApiError(e, source.path) } } @@ -257,8 +255,8 @@ internal class S3Impl(context: Context, cloud: S3Cloud) { progressAware.onProgress(Progress.completed(UploadState.upload(file))) return S3CloudNodeFactory.file(file.parent, file.name, size, lastModified) - } catch (ex: Exception) { - throw handleApiError(ex, file.path) + } catch (e: ErrorResponseException) { + throw handleApiError(e, file.path) } } } ?: throw FatalBackendException("InputStream shouldn't bee null") @@ -281,8 +279,8 @@ internal class S3Impl(context: Context, cloud: S3Cloud) { } }.use { out -> CopyStream.copyStreamToStream(response, out) } } - } catch (ex: Exception) { - throw handleApiError(ex, file.path) + } catch (e: ErrorResponseException) { + throw handleApiError(e, file.path) } progressAware.onProgress(Progress.completed(DownloadState.download(file))) } @@ -307,7 +305,7 @@ internal class S3Impl(context: Context, cloud: S3Cloud) { DeleteObject(item.objectName()) } } - } catch (e: Exception) { + } catch (e: ErrorResponseException) { throw handleApiError(e, node.path) } @@ -317,18 +315,18 @@ internal class S3Impl(context: Context, cloud: S3Cloud) { try { val error = result.get() Timber.tag("S3Impl").e("Error in deleting object " + error.objectName() + "; " + error.message()) - } catch (e: Exception) { + } catch (e: ErrorResponseException) { throw handleApiError(e, node.path) } } } - @Throws(IOException::class, BackendException::class) + //@Throws(IOException::class, BackendException::class) private fun deleteFile(node: S3File) { val removeObjectArgs = RemoveObjectArgs.builder().bucket(cloud.s3Bucket()).`object`(node.key).build() try { client().removeObject(removeObjectArgs) - } catch (e: Exception) { + } catch (e: ErrorResponseException) { throw handleApiError(e, "") } } @@ -340,15 +338,14 @@ internal class S3Impl(context: Context, cloud: S3Cloud) { throw NoSuchBucketException(cloud.s3Bucket()) } "" - } catch (e: Exception) { + } catch (e: ErrorResponseException) { throw handleApiError(e, "") } } - private fun handleApiError(ex: Exception, name: String): Exception { - return if (ex is ErrorResponseException) { - val errorCode = ex.errorResponse().code() - when { + private fun handleApiError(e: ErrorResponseException, name: String): Exception { + val errorCode = e.errorResponse().code() + return when { isAccessProblem(errorCode) -> { ForbiddenException() } @@ -359,12 +356,9 @@ internal class S3Impl(context: Context, cloud: S3Cloud) { NoSuchCloudFileException(name) } else -> { - FatalBackendException(ex) + FatalBackendException(e) } } - } else { - FatalBackendException(ex) - } } companion object { diff --git a/data/src/main/java/org/cryptomator/data/cloud/webdav/network/WebDavCompatibleHttpClient.kt b/data/src/main/java/org/cryptomator/data/cloud/webdav/network/WebDavCompatibleHttpClient.kt index c0dea8cf..b6367775 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/webdav/network/WebDavCompatibleHttpClient.kt +++ b/data/src/main/java/org/cryptomator/data/cloud/webdav/network/WebDavCompatibleHttpClient.kt @@ -16,6 +16,7 @@ import org.cryptomator.domain.WebDavCloud import org.cryptomator.domain.exception.UnableToDecryptWebdavPasswordException import org.cryptomator.util.SharedPreferencesHandler import org.cryptomator.util.crypto.CredentialCryptor +import org.cryptomator.util.crypto.FatalCryptoException import org.cryptomator.util.file.LruFileCacheUtil import java.io.IOException import java.nio.charset.StandardCharsets @@ -128,7 +129,7 @@ internal class WebDavCompatibleHttpClient(cloud: WebDavCloud, context: Context) CredentialCryptor // .getInstance(context) // .decrypt(password) - } catch (e: RuntimeException) { + } catch (e: FatalCryptoException) { throw UnableToDecryptWebdavPasswordException(e) } } diff --git a/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/GoogleDriveClientFactory.kt b/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/GoogleDriveClientFactory.kt index fe8c13ec..8cdb15f1 100644 --- a/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/GoogleDriveClientFactory.kt +++ b/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/GoogleDriveClientFactory.kt @@ -26,7 +26,7 @@ class GoogleDriveClientFactory internal constructor() { @Throws(FatalBackendException::class) fun createClient(accountName: String, context: Context): Drive { - if ( SharedPreferencesHandler(context).debugMode()) { + if (SharedPreferencesHandler(context).debugMode()) { Logger.getLogger("com.google.api.client").level = Level.CONFIG Logger.getLogger("com.google.api.client").addHandler(object : Handler() { override fun publish(record: LogRecord) { @@ -45,15 +45,11 @@ class GoogleDriveClientFactory internal constructor() { } }) } - return try { - val credential: FixedGoogleAccountCredential = FixedGoogleAccountCredential.usingOAuth2(context, setOf(DriveScopes.DRIVE)) - credential.setAccountName(accountName) - Drive.Builder(NetHttpTransport(), JacksonFactory.getDefaultInstance(), credential) // - .setApplicationName("Cryptomator-Android/" + BuildConfig.VERSION_NAME) // - .build() - } catch (e: Exception) { - throw FatalBackendException(e) - } + val credential = FixedGoogleAccountCredential.usingOAuth2(context, setOf(DriveScopes.DRIVE)).also { it.setAccountName(accountName) } + return Drive.Builder(NetHttpTransport(), JacksonFactory.getDefaultInstance(), credential) // + .setApplicationName("Cryptomator-Android/" + BuildConfig.VERSION_NAME) // + .build() + } } } diff --git a/domain/src/test/java/org/cryptomator/domain/usecases/cloud/DataSourceCapturingAnswer.kt b/domain/src/test/java/org/cryptomator/domain/usecases/cloud/DataSourceCapturingAnswer.kt index 514b9865..7975ae63 100644 --- a/domain/src/test/java/org/cryptomator/domain/usecases/cloud/DataSourceCapturingAnswer.kt +++ b/domain/src/test/java/org/cryptomator/domain/usecases/cloud/DataSourceCapturingAnswer.kt @@ -1,6 +1,7 @@ package org.cryptomator.domain.usecases.cloud import android.content.Context +import org.cryptomator.domain.exception.FatalBackendException import org.mockito.invocation.InvocationOnMock import org.mockito.kotlin.mock import org.mockito.stubbing.Answer @@ -30,7 +31,7 @@ internal class DataSourceCapturingAnswer(private val result: T, private val a out.write(buffer, 0, read) } } catch (e: IOException) { - throw RuntimeException(e) + throw FatalBackendException(e) } }