Calendar sync failed: Error while applying remote entries
I have the syncbase app on my mac desktop, as well as the client on android. What I think happened is I accepted a cal invite on my desktop, and now it has caused this exception on android every time it tries to sync:
I'm not sure exactly which invite is causing this, but please let me know if there's more information I can gather.
2021-04-19 09:52:56 1003 [ICalendar] Parsing iCalendar stream
2021-04-19 09:52:56 1003 Unfolding...
2021-04-19 09:52:56 1003 Unfolding...
2021-04-19 09:52:56 1003 [com.etesync.syncadapter.syncadapter.SyncNotification] Unknown sync error
EXCEPTION at.bitfire.ical4android.InvalidCalendarException: Couldn't parse iCalendar
at at.bitfire.ical4android.ICalendar$Companion.fromReader(ICalendar.kt:84)
at at.bitfire.ical4android.Event$Companion.eventsFromReader(Event.kt:85)
at at.bitfire.ical4android.Event$Companion.eventsFromReader$default(Event.kt:84)
at com.etesync.syncadapter.syncadapter.CalendarSyncManager.processItem(CalendarSyncManager.kt:89)
at com.etesync.syncadapter.syncadapter.SyncManager.applyRemoteItems(SyncManager.kt:470)
at com.etesync.syncadapter.syncadapter.SyncManager.performSync(SyncManager.kt:252)
at com.etesync.syncadapter.syncadapter.CalendarsSyncAdapterService$SyncAdapter.onPerformSyncDo(CalendarsSyncAdapterService.kt:50)
at com.etesync.syncadapter.syncadapter.SyncAdapterService$SyncAdapter.onPerformSync(SyncAdapterService.kt:117)
at android.content.AbstractThreadedSyncAdapter$SyncThread.run(AbstractThreadedSyncAdapter.java:334)
Caused by: net.fortuna.ical4j.data.ParserException: Error at line 15:String index out of range: -1
at net.fortuna.ical4j.data.CalendarParserImpl.parse(CalendarParserImpl.java:160)
at net.fortuna.ical4j.data.CalendarBuilder.build(CalendarBuilder.java:183)
at net.fortuna.ical4j.data.CalendarBuilder.build(CalendarBuilder.java:171)
at at.bitfire.ical4android.ICalendar$Companion.fromReader(ICalendar.kt:82)
... 8 more
Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(String.java:2064)
at net.fortuna.ical4j.model.property.Geo.setValue(Geo.java:209)
at net.fortuna.ical4j.model.property.Geo.<init>(Geo.java:166)
at net.fortuna.ical4j.model.property.Geo$Factory.createProperty(Geo.java:255)
at net.fortuna.ical4j.model.PropertyBuilder.build(PropertyBuilder.java:48)
at net.fortuna.ical4j.data.DefaultContentHandler.endProperty(DefaultContentHandler.java:123)
at net.fortuna.ical4j.data.CalendarParserImpl$PropertyParser.parse(CalendarParserImpl.java:294)
at net.fortuna.ical4j.data.CalendarParserImpl$PropertyParser.access$1100(CalendarParserImpl.java:226)
at net.fortuna.ical4j.data.CalendarParserImpl$PropertyListParser.parse(CalendarParserImpl.java:213)
at net.fortuna.ical4j.data.CalendarParserImpl$ComponentParser.parse(CalendarParserImpl.java:429)
at net.fortuna.ical4j.data.CalendarParserImpl$ComponentParser.access$900(CalendarParserImpl.java:406)
at net.fortuna.ical4j.data.CalendarParserImpl$PropertyListParser.parse(CalendarParserImpl.java:211)
at net.fortuna.ical4j.data.CalendarParserImpl.parseCalendar(CalendarParserImpl.java:116)
at net.fortuna.ical4j.data.CalendarParserImpl.parseCalendarList(CalendarParserImpl.java:182)
at net.fortuna.ical4j.data.CalendarParserImpl.parse(CalendarParserImpl.java:151)
... 11 more
2021-04-19 09:52:56 1003 [com.etesync.syncadapter.syncadapter.CalendarsSyncAdapterService] Calendar sync complete
2021-04-19 09:52:56 898 [com.etesync.syncadapter.AccountSettings] Account <myaccount> has version 2, current version: 2
Same issue here, but on Android with the EteSync client:
--- BEGIN DEBUG INFO --- SYNCHRONIZATION INFO Synchronization phase: applying remote entries Account name: withheld Authority: com.android.calendar Debug activity source: class com.etesync.syncadapter.syncadapter.SyncNotification$NotificationHandlerActivity (Kotlin reflection is not available)
EXCEPTION:
at.bitfire.ical4android.InvalidCalendarException: Couldn't parse iCalendar
at at.bitfire.ical4android.ICalendar$Companion.fromReader(ICalendar.kt:84)
at at.bitfire.ical4android.Event$Companion.eventsFromReader(Event.kt:85)
at at.bitfire.ical4android.Event$Companion.eventsFromReader$default(Event.kt:84)
at com.etesync.syncadapter.syncadapter.CalendarSyncManager.processItem(CalendarSyncManager.kt:89)
at com.etesync.syncadapter.syncadapter.SyncManager.applyRemoteItems(SyncManager.kt:470)
at com.etesync.syncadapter.syncadapter.SyncManager.performSync(SyncManager.kt:252)
at com.etesync.syncadapter.syncadapter.CalendarsSyncAdapterService$SyncAdapter.onPerformSyncDo(CalendarsSyncAdapterService.kt:50)
at com.etesync.syncadapter.syncadapter.SyncAdapterService$SyncAdapter.onPerformSync(SyncAdapterService.kt:117)
at android.content.AbstractThreadedSyncAdapter$SyncThread.run(AbstractThreadedSyncAdapter.java:334)
Caused by: net.fortuna.ical4j.data.ParserException: Error at line 15:Text cannot be parsed to a Duration
at net.fortuna.ical4j.data.CalendarParserImpl.parse(CalendarParserImpl.java:160)
at net.fortuna.ical4j.data.CalendarBuilder.build(CalendarBuilder.java:183)
at net.fortuna.ical4j.data.CalendarBuilder.build(CalendarBuilder.java:171)
at at.bitfire.ical4android.ICalendar$Companion.fromReader(ICalendar.kt:82)
... 8 more
Caused by: j$.time.format.x: Text cannot be parsed to a Duration
at j$.time.Duration.parse(:412)
at net.fortuna.ical4j.model.TemporalAmountAdapter.parse(TemporalAmountAdapter.java:137)
at net.fortuna.ical4j.model.property.Trigger.setValue(Trigger.java:270)
at net.fortuna.ical4j.model.property.Trigger.
SOFTWARE INFORMATION EteSync version: 2.2.4 (20204) Installed from: com.google.android.packageinstaller CONFIGURATION Power saving disabled: yes android.permission.READ_CONTACTS permission: granted android.permission.WRITE_CONTACTS permission: granted android.permission.READ_CALENDAR permission: granted android.permission.WRITE_CALENDAR permission: granted org.dmfs.permission.READ_TASKS permission: denied org.dmfs.permission.WRITE_TASKS permission: denied org.tasks.permission.READ_TASKS permission: granted org.tasks.permission.WRITE_TASKS permission: granted System-wide synchronization: automatically Account: withheld Address book sync. interval: manually Calendar sync. interval: manually OpenTasks sync. interval: — Tasks.org sync. interval: manually WiFi only: false [CardDAV] Contact group method: GROUP_VCARDS Manage calendar colors: true Address book account: Contacts ( withheld L8) Main account: Account {name= withheld, type=com.etesync.syncadapter} URL: L8ZTDx4UFQi_np9YWKaHj0t-PAzmyjXu Sync automatically: true
SQLITE DUMP android_metadata | locale | | en_US |
settings | setting | value |
SERVICES DUMP
JOURNALS DUMP
SYSTEM INFORMATION Android version: 9 (PPS29.118-15-11-16) Device: Motorola moto g(6) (ali)
--- END DEBUG INFO ---
Okay, I was finally able to get a debug version installed and finished debugging.
In my case, the issue was that I had an iCal entry that contained this invalid field: GEO: (missing the coordinates and therefore not valid according to the spec: https://www.kanzaki.com/docs/ical/geo.html)
So what's going on here appears to be different parsing rules depending on the application. I believe this calendar was first imported into etesync via the MacOS calendar app. It must have succeeded the initial validation. However, when trying to sync the calendar app to the android client, the ical4j library doesn't like the entry, and throws an exception. This is especially problematic because it stops further processing and no more calendar entries are updated as long as a single calendar has a parsing issue.
I propose two fixes to this problem:
Easy workaround: Catch parsing exceptions and continue applying the remaining items. In its simplest, this just involves adding something similar to this try/catch:
private fun applyRemoteItems(itemList: ItemListResponse) {
val items = itemList.data
// Process new vcards from server
val size = items.size
var i = 0
for (item in items) {
if (Thread.interrupted()) {
throw InterruptedException()
}
i++
Logger.log.info("Processing (${i}/${size}) UID=${item.uid} Etag=${item.etag}")
try {
processItem(item)
persistItem(item)
} catch (e: InvalidCalendarException) {
Logger.log.warning("iCal item (${i}/${size}) was invalid and could not be parsed. UID=${item.uid} Etag=${item.etag}")
}
}
}
in syncmanager.kt
Pros: Easy fix, Reduction of severity - one bad cal entry doesn't prevent syncing the remaining cal entries Cons: Users aren't notified that some of their cal entries didn't sync because of a parsing bug
IMO a better, but more involved solution would be to notify the user that the remote cal entry has a bug, and offer to delete (or re-create) the cal entry.