diff options
author | Patrick Ohly <patrick.ohly@intel.com> | 2011-08-03 12:59:43 +0200 |
---|---|---|
committer | Patrick Ohly <patrick.ohly@intel.com> | 2011-08-03 13:09:30 +0200 |
commit | cb25e44871eee615f1b3fc75163bc0f783120dc9 (patch) | |
tree | be4c7fb5c4a9beb4b9da159649dea99ebc6dae59 /src/backends/webdav/CalDAVSource.cpp | |
parent | ac8fdc42b46a0b31f50a054647cef4df2d09b81c (diff) |
CalDAV: continue despite Google Calendar access problems (see BMC #19484)
Google Calendar checks whether a CalDAV client is allowed to update
particular events. In combination with meeting invitations this has
led to know issues where desirable changes were rejected (see
http://code.google.com/p/google-caldav-issues/issues/detail?id=38).
Details are murky whether that bug is still open. I hit the "403 You
don't have access to change that event." problem both in updating
a meeting series and creating it.
This commit ensures that when updating fails, the errors is treated as
a temporary, per item error (417). The sync session then continues.
The overall result will be STATUS_PARTIAL_FAILURE = 22001 and the
next session will retry the same item. This is better than aborting
the session (situation without this patch) or ignoring the problem
(alternative solution).
The same error is not handled when creation fails. This might need
further investigations.
Diffstat (limited to 'src/backends/webdav/CalDAVSource.cpp')
-rw-r--r-- | src/backends/webdav/CalDAVSource.cpp | 46 |
1 files changed, 39 insertions, 7 deletions
diff --git a/src/backends/webdav/CalDAVSource.cpp b/src/backends/webdav/CalDAVSource.cpp index 583645dd..3fbdbc70 100644 --- a/src/backends/webdav/CalDAVSource.cpp +++ b/src/backends/webdav/CalDAVSource.cpp @@ -421,6 +421,7 @@ SubSyncSource::SubItemResult CalDAVSource::insertSubItem(const std::string &luid Event::escapeRecurrenceID(buffer); data = &buffer; } + SE_LOG_DEBUG(this, NULL, "inserting new VEVENT"); res = insertItem(name, *data, true); subres.m_mainid = res.m_luid; subres.m_uid = newEvent->m_UID; @@ -580,14 +581,45 @@ SubSyncSource::SubItemResult CalDAVSource::insertSubItem(const std::string &luid } // TODO: avoid updating item on server immediately? - InsertItemResult res = insertItem(event.m_DAVluid, data, true); - if (res.m_merged || - res.m_luid != event.m_DAVluid) { - // should not merge with anything, if so, our cache was invalid - SE_THROW("CalDAV item not updated as expected"); + try { + SE_LOG_DEBUG(this, NULL, "updating VEVENT"); + InsertItemResult res = insertItem(event.m_DAVluid, data, true); + if (res.m_merged || + res.m_luid != event.m_DAVluid) { + // should not merge with anything, if so, our cache was invalid + SE_THROW("CalDAV item not updated as expected"); + } + event.m_etag = res.m_revision; + subres.m_revision = event.m_etag; + } catch (const TransportStatusException &ex) { + if (ex.syncMLStatus() == 403 && + strstr(ex.what(), "You don't have access to change that event")) { + // Google Calendar sometimes refuses writes for specific items, + // typically meetings organized by someone else. +#if 1 + // Treat like a temporary, per item error to avoid aborting the + // whole sync session. Doesn't really solve the problem (client + // and server remain out of sync and will run into this again and + // again), but better than giving up on all items or ignoring the + // problem. + SE_THROW_EXCEPTION_STATUS(StatusException, + "CalDAV peer rejected updated with 403, keep trying", + SyncMLStatus(417)); +#else + // Assume that the item hasn't changed and mark it as "merged". + // This is incorrect. The 403 error has been seen in cases where + // a detached recurrence had to be added to an existing meeting + // series. Ignoring the problem means would keep the detached + // recurrence out of the server permanently. + SE_LOG_INFO(this, NULL, "%s: not updated because CalDAV server refused write access for it", + getSubDescription(event, subid).c_str()); + subres.m_merged = true; + subres.m_revision = event.m_etag; +#endif + } else { + throw; + } } - event.m_etag = res.m_revision; - subres.m_revision = event.m_etag; } return subres; |