From 1fcd80f5a7dfaf8c0bf412d4b9ba6d551618bd0d Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Fri, 9 Feb 2024 15:40:03 -0300 Subject: [PATCH] Tolerate unexpected exceptions in DocumentsStorage and ApkRestore --- .../seedvault/plugins/saf/DocumentsStorage.kt | 22 ++++++++++++++----- .../seedvault/restore/install/ApkRestore.kt | 3 +++ .../seedvault/transport/backup/ApkBackup.kt | 7 ++---- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/stevesoltys/seedvault/plugins/saf/DocumentsStorage.kt b/app/src/main/java/com/stevesoltys/seedvault/plugins/saf/DocumentsStorage.kt index 7e970a736..593f49437 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/plugins/saf/DocumentsStorage.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/plugins/saf/DocumentsStorage.kt @@ -134,12 +134,22 @@ internal class DocumentsStorage( @Throws(IOException::class) fun getInputStream(file: DocumentFile): InputStream { - return contentResolver.openInputStream(file.uri) ?: throw IOException() + return try { + contentResolver.openInputStream(file.uri) ?: throw IOException() + } catch (e: Exception) { + // SAF can throw all sorts of exceptions, so wrap it in IOException + throw IOException(e) + } } @Throws(IOException::class) fun getOutputStream(file: DocumentFile): OutputStream { - return contentResolver.openOutputStream(file.uri, "wt") ?: throw IOException() + return try { + contentResolver.openOutputStream(file.uri, "wt") ?: throw IOException() + } catch (e: Exception) { + // SAF can throw all sorts of exceptions, so wrap it in IOException + throw IOException(e) + } } } @@ -161,8 +171,10 @@ internal suspend fun DocumentFile.createOrGetFile( throw IOException("File named ${this.name}, but should be $name") } } ?: throw IOException() - } catch (e: IllegalArgumentException) { - // Can be thrown by FileSystemProvider#isChildDocument() when flash drive is not plugged-in + } catch (e: Exception) { + // SAF can throw all sorts of exceptions, so wrap it in IOException. + // E.g. IllegalArgumentException can be thrown by FileSystemProvider#isChildDocument() + // when flash drive is not plugged-in: // http://aosp.opersys.com/xref/android-11.0.0_r8/xref/frameworks/base/core/java/com/android/internal/content/FileSystemProvider.java#135 throw IOException(e) } @@ -248,7 +260,7 @@ internal fun getTreeDocumentFile(parent: DocumentFile, context: Context, uri: Ur suspend fun DocumentFile.findFileBlocking(context: Context, displayName: String): DocumentFile? { val files = try { listFilesBlocking(context) - } catch (e: IOException) { + } catch (e: Exception) { Log.e(TAG, "Error finding file blocking", e) return null } diff --git a/app/src/main/java/com/stevesoltys/seedvault/restore/install/ApkRestore.kt b/app/src/main/java/com/stevesoltys/seedvault/restore/install/ApkRestore.kt index 59600b3d6..c469f0031 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/restore/install/ApkRestore.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/restore/install/ApkRestore.kt @@ -76,6 +76,9 @@ internal class ApkRestore( } catch (e: TimeoutCancellationException) { Log.e(TAG, "Timeout while re-installing APK for $packageName.", e) emit(installResult.fail(packageName)) + } catch (e: Exception) { + Log.e(TAG, "Unexpected exception while re-installing APK for $packageName.", e) + emit(installResult.fail(packageName)) } } installResult.isFinished = true diff --git a/app/src/main/java/com/stevesoltys/seedvault/transport/backup/ApkBackup.kt b/app/src/main/java/com/stevesoltys/seedvault/transport/backup/ApkBackup.kt index 1942f0061..b248b8d3c 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/transport/backup/ApkBackup.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/transport/backup/ApkBackup.kt @@ -17,7 +17,6 @@ import com.stevesoltys.seedvault.metadata.PackageState import com.stevesoltys.seedvault.settings.SettingsManager import java.io.File import java.io.FileInputStream -import java.io.FileNotFoundException import java.io.IOException import java.io.InputStream import java.io.OutputStream @@ -145,10 +144,8 @@ internal class ApkBackup( val apk = File(apkPath) return try { apk.inputStream() - } catch (e: FileNotFoundException) { - Log.e(TAG, "Error opening ${apk.absolutePath} for backup.", e) - throw IOException(e) - } catch (e: SecurityException) { + } catch (e: Exception) { + // SAF may throw all sorts of exceptions, so wrap them in IOException Log.e(TAG, "Error opening ${apk.absolutePath} for backup.", e) throw IOException(e) }