Try to show more relevant exception messages when failing to restore a backup

This commit is contained in:
arkon 2022-01-26 22:43:27 -05:00
parent 76d2c676fd
commit b459234ddc
4 changed files with 30 additions and 15 deletions

View File

@ -14,3 +14,5 @@ abstract class AbstractBackupRestoreValidator {
data class Results(val missingSources: List<String>, val missingTrackers: List<String>) data class Results(val missingSources: List<String>, val missingTrackers: List<String>)
} }
class ValidatorParseException(e: Exception) : RuntimeException(e)

View File

@ -4,12 +4,14 @@ import android.content.Context
import android.net.Uri import android.net.Uri
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.backup.AbstractBackupRestoreValidator import eu.kanade.tachiyomi.data.backup.AbstractBackupRestoreValidator
import eu.kanade.tachiyomi.data.backup.ValidatorParseException
import eu.kanade.tachiyomi.data.backup.full.models.BackupSerializer import eu.kanade.tachiyomi.data.backup.full.models.BackupSerializer
import okio.buffer import okio.buffer
import okio.gzip import okio.gzip
import okio.source import okio.source
class FullBackupRestoreValidator : AbstractBackupRestoreValidator() { class FullBackupRestoreValidator : AbstractBackupRestoreValidator() {
/** /**
* Checks for critical backup file data. * Checks for critical backup file data.
* *
@ -19,14 +21,20 @@ class FullBackupRestoreValidator : AbstractBackupRestoreValidator() {
override fun validate(context: Context, uri: Uri): Results { override fun validate(context: Context, uri: Uri): Results {
val backupManager = FullBackupManager(context) val backupManager = FullBackupManager(context)
val backupString = context.contentResolver.openInputStream(uri)!!.source().gzip().buffer().use { it.readByteArray() } val backup = try {
val backup = backupManager.parser.decodeFromByteArray(BackupSerializer, backupString) val backupString =
context.contentResolver.openInputStream(uri)!!.source().gzip().buffer()
.use { it.readByteArray() }
backupManager.parser.decodeFromByteArray(BackupSerializer, backupString)
} catch (e: Exception) {
throw ValidatorParseException(e)
}
if (backup.backupManga.isEmpty()) { if (backup.backupManga.isEmpty()) {
throw Exception(context.getString(R.string.invalid_backup_file_missing_manga)) throw Exception(context.getString(R.string.invalid_backup_file_missing_manga))
} }
val sources = backup.backupSources.map { it.sourceId to it.name }.toMap() val sources = backup.backupSources.associate { it.sourceId to it.name }
val missingSources = sources val missingSources = sources
.filter { sourceManager.get(it.key) == null } .filter { sourceManager.get(it.key) == null }
.values .values

View File

@ -4,10 +4,12 @@ import android.content.Context
import android.net.Uri import android.net.Uri
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.backup.AbstractBackupRestoreValidator import eu.kanade.tachiyomi.data.backup.AbstractBackupRestoreValidator
import eu.kanade.tachiyomi.data.backup.ValidatorParseException
import eu.kanade.tachiyomi.data.backup.legacy.models.Backup import eu.kanade.tachiyomi.data.backup.legacy.models.Backup
import kotlinx.serialization.json.decodeFromStream import kotlinx.serialization.json.decodeFromStream
class LegacyBackupRestoreValidator : AbstractBackupRestoreValidator() { class LegacyBackupRestoreValidator : AbstractBackupRestoreValidator() {
/** /**
* Checks for critical backup file data. * Checks for critical backup file data.
* *
@ -17,9 +19,13 @@ class LegacyBackupRestoreValidator : AbstractBackupRestoreValidator() {
override fun validate(context: Context, uri: Uri): Results { override fun validate(context: Context, uri: Uri): Results {
val backupManager = LegacyBackupManager(context) val backupManager = LegacyBackupManager(context)
val backup = backupManager.parser.decodeFromStream<Backup>( val backup = try {
context.contentResolver.openInputStream(uri)!! backupManager.parser.decodeFromStream<Backup>(
) context.contentResolver.openInputStream(uri)!!
)
} catch (e: Exception) {
throw ValidatorParseException(e)
}
if (backup.version == null) { if (backup.version == null) {
throw Exception(context.getString(R.string.invalid_backup_file_missing_data)) throw Exception(context.getString(R.string.invalid_backup_file_missing_data))
@ -51,12 +57,10 @@ class LegacyBackupRestoreValidator : AbstractBackupRestoreValidator() {
companion object { companion object {
fun getSourceMapping(extensionsMapping: List<String>): Map<Long, String> { fun getSourceMapping(extensionsMapping: List<String>): Map<Long, String> {
return extensionsMapping return extensionsMapping.associate {
.map { val items = it.split(":")
val items = it.split(":") items[0].toLong() to items[1]
items[0].toLong() to items[1] }
}
.toMap()
} }
} }
} }

View File

@ -20,6 +20,7 @@ import eu.kanade.tachiyomi.data.backup.BackupConst
import eu.kanade.tachiyomi.data.backup.BackupCreateService import eu.kanade.tachiyomi.data.backup.BackupCreateService
import eu.kanade.tachiyomi.data.backup.BackupCreatorJob import eu.kanade.tachiyomi.data.backup.BackupCreatorJob
import eu.kanade.tachiyomi.data.backup.BackupRestoreService import eu.kanade.tachiyomi.data.backup.BackupRestoreService
import eu.kanade.tachiyomi.data.backup.ValidatorParseException
import eu.kanade.tachiyomi.data.backup.full.FullBackupRestoreValidator import eu.kanade.tachiyomi.data.backup.full.FullBackupRestoreValidator
import eu.kanade.tachiyomi.data.backup.full.models.BackupFull import eu.kanade.tachiyomi.data.backup.full.models.BackupFull
import eu.kanade.tachiyomi.data.backup.legacy.LegacyBackupRestoreValidator import eu.kanade.tachiyomi.data.backup.legacy.LegacyBackupRestoreValidator
@ -262,12 +263,12 @@ class SettingsBackupController : SettingsController() {
return try { return try {
var type = BackupConst.BACKUP_TYPE_FULL var type = BackupConst.BACKUP_TYPE_FULL
val results = runCatching { val results = try {
FullBackupRestoreValidator().validate(activity, uri) FullBackupRestoreValidator().validate(activity, uri)
}.recoverCatching { } catch (_: ValidatorParseException) {
type = BackupConst.BACKUP_TYPE_LEGACY type = BackupConst.BACKUP_TYPE_LEGACY
LegacyBackupRestoreValidator().validate(activity, uri) LegacyBackupRestoreValidator().validate(activity, uri)
}.getOrThrow() }
var message = if (type == BackupConst.BACKUP_TYPE_FULL) { var message = if (type == BackupConst.BACKUP_TYPE_FULL) {
activity.getString(R.string.backup_restore_content_full) activity.getString(R.string.backup_restore_content_full)