From 9f6b63620e49a9b4217269d2e4700b0107ed36a3 Mon Sep 17 00:00:00 2001 From: Tom Hacohen Date: Fri, 28 Feb 2020 12:40:43 +0200 Subject: [PATCH] Sync: make malformed entry errors non-fatal. What we do is we mark them as failed and note the error, though we don't currently have a way to notify the user about these errors. This will follow in the next commit. --- .../main/java/com/etesync/syncadapter/App.kt | 2 +- .../syncadapter/model/JournalModel.java | 17 ++++++++++++++++ .../syncadapter/syncadapter/SyncManager.kt | 20 ++++++++++++++----- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/etesync/syncadapter/App.kt b/app/src/main/java/com/etesync/syncadapter/App.kt index d3c28699..7f9e10bd 100644 --- a/app/src/main/java/com/etesync/syncadapter/App.kt +++ b/app/src/main/java/com/etesync/syncadapter/App.kt @@ -55,7 +55,7 @@ class App : Application() { get() = initDataStore() fun initDataStore(): MyEntityDataStore { - val source = MyDatabaseSource(this, Models.DEFAULT, 4) + val source = MyDatabaseSource(this, Models.DEFAULT, 5) val configuration = source.configuration return MyEntityDataStore(configuration) } diff --git a/app/src/main/java/com/etesync/syncadapter/model/JournalModel.java b/app/src/main/java/com/etesync/syncadapter/model/JournalModel.java index 310d5f73..2c7f7917 100644 --- a/app/src/main/java/com/etesync/syncadapter/model/JournalModel.java +++ b/app/src/main/java/com/etesync/syncadapter/model/JournalModel.java @@ -13,6 +13,7 @@ import io.requery.Generated; import io.requery.Index; import io.requery.Key; import io.requery.ManyToOne; +import io.requery.OneToOne; import io.requery.PostLoad; import io.requery.ReferentialAction; import io.requery.Table; @@ -157,6 +158,22 @@ public class JournalModel { } } + @Entity + @Table(name = "EntryError", uniqueIndexes = "entry_unique_together") + public static abstract class EntryError { + @Key + @Generated + int id; + + @Column(nullable = false) + String error; + + @Index("entry_unique_together") + @ForeignKey(update = ReferentialAction.CASCADE) + @OneToOne + Entry entry; + } + static class CollectionInfoConverter implements Converter { @Override public Class getMappedType() { diff --git a/app/src/main/java/com/etesync/syncadapter/syncadapter/SyncManager.kt b/app/src/main/java/com/etesync/syncadapter/syncadapter/SyncManager.kt index 2db5fb0d..28a21ff5 100644 --- a/app/src/main/java/com/etesync/syncadapter/syncadapter/SyncManager.kt +++ b/app/src/main/java/com/etesync/syncadapter/syncadapter/SyncManager.kt @@ -299,13 +299,17 @@ constructor(protected val context: Context, protected val account: Account, prot } } - private fun persistSyncEntry(uid: String?, syncEntry: SyncEntry) { + private fun persistSyncEntry(uid: String?, syncEntry: SyncEntry, error: String?) { val entry = EntryEntity() entry.uid = uid entry.content = syncEntry entry.journal = journalEntity try { data.insert(entry) + val entryError = EntryErrorEntity() + entryError.entry = entry + entryError.error = error + data.insert(entryError) } catch (e: io.requery.sql.StatementExecutionException) { if (e.cause is java.sql.SQLIntegrityConstraintViolationException) { Logger.log.warning("Tried inserting an existing entry ${uid}") @@ -352,7 +356,7 @@ constructor(protected val context: Context, protected val account: Account, prot var i = 0 for (entry in remoteEntries!!) { val cEntry = SyncEntry.fromJournalEntry(crypto, entry) - persistSyncEntry(entry.uid, cEntry) + persistSyncEntry(entry.uid, cEntry, null) i++ if (remoteCTag == entry.uid) { remoteEntries = remoteEntries?.drop(i) @@ -381,9 +385,15 @@ constructor(protected val context: Context, protected val account: Account, prot val cEntry = SyncEntry.fromJournalEntry(crypto, entry) Logger.log.info("Processing resource for journal entry") - processSyncEntry(cEntry) - persistSyncEntry(entry.uid, cEntry) + var error: String? = null + try { + processSyncEntry(cEntry) + } catch (e: Exception) { + error = e.toString() + } + + persistSyncEntry(entry.uid, cEntry, error) remoteCTag = entry.uid } @@ -404,7 +414,7 @@ constructor(protected val context: Context, protected val account: Account, prot // Persist the entries after they've been pushed for (entry in entries) { val cEntry = SyncEntry.fromJournalEntry(crypto, entry) - persistSyncEntry(entry.uid, cEntry) + persistSyncEntry(entry.uid, cEntry, null) } remoteCTag = entries[entries.size - 1].uid pushed += entries.size