Catch error when loading snapshots for app checking
This commit is contained in:
parent
83974b4121
commit
06191a1fc3
4 changed files with 49 additions and 26 deletions
|
@ -49,20 +49,25 @@ internal class Checker(
|
||||||
private set
|
private set
|
||||||
|
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
suspend fun getBackupSize(): Long {
|
suspend fun getBackupSize(): Long? {
|
||||||
// get all snapshots
|
// get all snapshots
|
||||||
val folder = TopLevelFolder(crypto.repoId)
|
val folder = TopLevelFolder(crypto.repoId)
|
||||||
val handles = mutableListOf<AppBackupFileType.Snapshot>()
|
val handles = mutableListOf<AppBackupFileType.Snapshot>()
|
||||||
|
try {
|
||||||
backendManager.backend.list(folder, AppBackupFileType.Snapshot::class) { fileInfo ->
|
backendManager.backend.list(folder, AppBackupFileType.Snapshot::class) { fileInfo ->
|
||||||
handles.add(fileInfo.fileHandle as AppBackupFileType.Snapshot)
|
handles.add(fileInfo.fileHandle as AppBackupFileType.Snapshot)
|
||||||
}
|
}
|
||||||
val snapshots = snapshotManager.onSnapshotsLoaded(handles)
|
val snapshots = snapshotManager.onSnapshotsLoaded(handles)
|
||||||
this.snapshots = snapshots // remember loaded snapshots
|
this.snapshots = snapshots // remember loaded snapshots
|
||||||
this.handleSize = handles.size // remember number of snapshot handles we had
|
this.handleSize = handles.size // remember number of snapshot handles we had
|
||||||
|
} catch (e: Exception) {
|
||||||
|
log.error(e) { "Error loading snapshots: " }
|
||||||
|
// we swallow this exception, because an error will be shown in the next step
|
||||||
|
return null
|
||||||
|
}
|
||||||
// get total disk space used by snapshots
|
// get total disk space used by snapshots
|
||||||
val sizeMap = mutableMapOf<String, Int>()
|
val sizeMap = mutableMapOf<String, Int>()
|
||||||
snapshots.forEach { snapshot ->
|
snapshots?.forEach { snapshot ->
|
||||||
// add sizes to a map first, so we don't double count
|
// add sizes to a map first, so we don't double count
|
||||||
snapshot.blobsMap.forEach { (chunkId, blob) -> sizeMap[chunkId] = blob.length }
|
snapshot.blobsMap.forEach { (chunkId, blob) -> sizeMap[chunkId] = blob.length }
|
||||||
}
|
}
|
||||||
|
@ -73,7 +78,12 @@ internal class Checker(
|
||||||
suspend fun check(percent: Int) {
|
suspend fun check(percent: Int) {
|
||||||
check(percent in 0..100) { "Percent $percent out of bounds." }
|
check(percent in 0..100) { "Percent $percent out of bounds." }
|
||||||
|
|
||||||
if (snapshots == null) getBackupSize() // just get size again to be sure we get snapshots
|
if (snapshots == null) try {
|
||||||
|
getBackupSize() // just get size again to be sure we get snapshots
|
||||||
|
} catch (e: Exception) {
|
||||||
|
nm.onCheckFinishedWithError(0, 0)
|
||||||
|
checkerResult = CheckerResult.GeneralError(e)
|
||||||
|
}
|
||||||
val snapshots = snapshots ?: error("Snapshots still null")
|
val snapshots = snapshots ?: error("Snapshots still null")
|
||||||
val handleSize = handleSize ?: error("Handle size still null")
|
val handleSize = handleSize ?: error("Handle size still null")
|
||||||
check(handleSize >= snapshots.size) {
|
check(handleSize >= snapshots.size) {
|
||||||
|
|
|
@ -50,9 +50,11 @@ class AppCheckFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.backupSize.observe(viewLifecycleOwner) {
|
viewModel.backupSize.observe(viewLifecycleOwner) {
|
||||||
|
if (it != null) {
|
||||||
slider.labelBehavior = LABEL_VISIBLE
|
slider.labelBehavior = LABEL_VISIBLE
|
||||||
slider.invalidate()
|
slider.invalidate()
|
||||||
onSliderChanged(slider.value)
|
onSliderChanged(slider.value)
|
||||||
|
}
|
||||||
// we can stop observing as the loaded size won't change again
|
// we can stop observing as the loaded size won't change again
|
||||||
viewModel.backupSize.removeObservers(viewLifecycleOwner)
|
viewModel.backupSize.removeObservers(viewLifecycleOwner)
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,9 +56,14 @@ class AppCheckResultActivity : BackupActivity() {
|
||||||
is CheckerResult.Success -> onSuccess(result)
|
is CheckerResult.Success -> onSuccess(result)
|
||||||
is CheckerResult.Error -> onError(result)
|
is CheckerResult.Error -> onError(result)
|
||||||
is CheckerResult.GeneralError, null -> {
|
is CheckerResult.GeneralError, null -> {
|
||||||
// TODO
|
if (result == null) {
|
||||||
if (result == null) log.error { "No more result" }
|
val str = getString(R.string.backup_app_check_error_no_result)
|
||||||
else log.info((result as CheckerResult.GeneralError).e) { "Error: " }
|
val e = NullPointerException(str)
|
||||||
|
val r = CheckerResult.GeneralError(e)
|
||||||
|
onGeneralError(r)
|
||||||
|
} else {
|
||||||
|
onGeneralError(result as CheckerResult.GeneralError)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checker.clear()
|
checker.clear()
|
||||||
|
@ -98,14 +103,8 @@ class AppCheckResultActivity : BackupActivity() {
|
||||||
R.string.backup_app_check_error_only_broken_snapshots,
|
R.string.backup_app_check_error_only_broken_snapshots,
|
||||||
result.existingSnapshots,
|
result.existingSnapshots,
|
||||||
)
|
)
|
||||||
} else if (result.existingSnapshots > result.snapshots.size) {
|
|
||||||
getString(
|
|
||||||
R.string.backup_app_check_error_some_snapshots,
|
|
||||||
result.existingSnapshots,
|
|
||||||
result.snapshots.size,
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
getString(R.string.backup_app_check_error_read_all_snapshots, result.snapshots.size)
|
getString(R.string.backup_app_check_error_has_snapshots, result.existingSnapshots)
|
||||||
}
|
}
|
||||||
requireViewById<TextView>(R.id.introView).text = intro
|
requireViewById<TextView>(R.id.introView).text = intro
|
||||||
|
|
||||||
|
@ -121,4 +120,16 @@ class AppCheckResultActivity : BackupActivity() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun onGeneralError(result: CheckerResult.GeneralError) {
|
||||||
|
setContentView(R.layout.activity_check_result)
|
||||||
|
requireViewById<ImageView>(R.id.imageView).setImageResource(R.drawable.ic_cloud_error)
|
||||||
|
requireViewById<TextView>(R.id.titleView).setText(R.string.backup_app_check_error_title)
|
||||||
|
|
||||||
|
requireViewById<TextView>(R.id.introView).text =
|
||||||
|
getString(R.string.backup_app_check_error_no_snapshots)
|
||||||
|
|
||||||
|
requireViewById<TextView>(R.id.disclaimerView).text =
|
||||||
|
"${result.e.localizedMessage}\n\n${result.e}"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,12 +196,12 @@
|
||||||
<string name="notification_checking_action">Details</string>
|
<string name="notification_checking_action">Details</string>
|
||||||
|
|
||||||
<string name="backup_app_check_success_intro">%1$d snapshots were found and %2$d%% of their data (%3$s) successfully verified:</string>
|
<string name="backup_app_check_success_intro">%1$d snapshots were found and %2$d%% of their data (%3$s) successfully verified:</string>
|
||||||
<string name="backup_app_check_success_disclaimer">Note: We can not verify whether apps include all of their data in the backup.</string>
|
<string name="backup_app_check_success_disclaimer">Note: we cannot verify whether individual apps include all of their user data in the backup.</string>
|
||||||
<string name="backup_app_check_error_title">@string/notification_checking_error_title</string>
|
<string name="backup_app_check_error_title">@string/notification_checking_error_title</string>
|
||||||
<string name="backup_app_check_error_no_snapshots">We could not find any backup. Please run a successful backup first and then try checking again.</string>
|
<string name="backup_app_check_error_no_snapshots">We could not find any backup. Please run a successful backup first and then try checking again.</string>
|
||||||
<string name="backup_app_check_error_only_broken_snapshots">We found %1$d backup snapshots. However, all of them were corrupted. Please run a successful backup and then try checking again.</string>
|
<string name="backup_app_check_error_only_broken_snapshots">We found %1$d backup snapshots. However, all of them were corrupted. Please run a successful backup and then try checking again.</string>
|
||||||
<string name="backup_app_check_error_some_snapshots">We found %1$d backup snapshots. However, we could only read the following %2$d snapshots.</string>
|
<string name="backup_app_check_error_has_snapshots">We found %1$d backup snapshots, some of them are corrupt or have errors. Below are the backups that could be restored.</string>
|
||||||
<string name="backup_app_check_error_read_all_snapshots">We found %1$d backup snapshots. However, some had errors and can not be fully restored.</string>
|
<string name="backup_app_check_error_no_result">We lost the detailed results. Did a long time pass since running the check? Try running again.</string>
|
||||||
|
|
||||||
<!-- App Backup and Restore State -->
|
<!-- App Backup and Restore State -->
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@
|
||||||
<string name="restore_restore_set_apps_no_size">Has user data for <xliff:g example="42" id="apps">%1$d</xliff:g> apps</string>
|
<string name="restore_restore_set_apps_no_size">Has user data for <xliff:g example="42" id="apps">%1$d</xliff:g> apps</string>
|
||||||
<string name="restore_restore_set_apks">Contains <xliff:g example="42" id="apps">%1$d</xliff:g> apps (<xliff:g example="1 GB" id="size">%2$s</xliff:g>)</string>
|
<string name="restore_restore_set_apks">Contains <xliff:g example="42" id="apps">%1$d</xliff:g> apps (<xliff:g example="1 GB" id="size">%2$s</xliff:g>)</string>
|
||||||
<string name="restore_restore_set_apks_no_size">Contains <xliff:g example="42" id="apps">%1$d</xliff:g> apps</string>
|
<string name="restore_restore_set_apks_no_size">Contains <xliff:g example="42" id="apps">%1$d</xliff:g> apps</string>
|
||||||
<string name="restore_restore_set_can_not_get_restored">Can not be (fully) restored.</string>
|
<string name="restore_restore_set_can_not_get_restored">This backup has some errors. You may be able to restore it partly.</string>
|
||||||
<string name="restore_skip">Don\'t restore</string>
|
<string name="restore_skip">Don\'t restore</string>
|
||||||
<string name="restore_skip_apps">Skip restoring apps</string>
|
<string name="restore_skip_apps">Skip restoring apps</string>
|
||||||
<string name="restore_invalid_location_title">No backups found</string>
|
<string name="restore_invalid_location_title">No backups found</string>
|
||||||
|
|
Loading…
Reference in a new issue