summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2023-03-29 10:45:16 +0200
committerMilan Crha <mcrha@redhat.com>2023-03-29 10:45:16 +0200
commit976fee2ff85fc94c1bc5cc925ca7a2e2ad131297 (patch)
tree181d1b0de8e0df172ded93f1a40a0e4d37a0ff53
parent27ce1d1ffdd35fda512f9d12351a90ae6e1ad989 (diff)
downloadevolution-data-server-976fee2ff85fc94c1bc5cc925ca7a2e2ad131297.tar.gz
I#462 - Fails to refresh backend with offline changes and broken local cache state
Closes https://gitlab.gnome.org/GNOME/evolution-data-server/-/issues/462
-rw-r--r--src/addressbook/backends/carddav/e-book-backend-carddav.c4
-rw-r--r--src/addressbook/libedata-book/e-book-meta-backend.c27
-rw-r--r--src/calendar/libedata-cal/e-cal-meta-backend.c27
3 files changed, 52 insertions, 6 deletions
diff --git a/src/addressbook/backends/carddav/e-book-backend-carddav.c b/src/addressbook/backends/carddav/e-book-backend-carddav.c
index f395808b5..311fda92b 100644
--- a/src/addressbook/backends/carddav/e-book-backend-carddav.c
+++ b/src/addressbook/backends/carddav/e-book-backend-carddav.c
@@ -1282,14 +1282,14 @@ ebb_carddav_save_contact_sync (EBookMetaBackend *meta_backend,
cache = e_book_meta_backend_ref_cache (meta_backend);
success = FALSE;
- g_propagate_error (error, e_client_error_create_fmt (E_CLIENT_ERROR_OTHER_ERROR,
+ g_propagate_error (error, e_client_error_create_fmt (E_CLIENT_ERROR_INVALID_ARG,
_("Missing information about component URL, local cache is possibly incomplete or broken. You can try to remove it and restart background evolution-data-server processes. Cache file: %s"),
e_cache_get_filename (E_CACHE (cache))));
g_clear_object (&cache);
} else {
success = FALSE;
- g_propagate_error (error, EC_ERROR_EX (E_CLIENT_ERROR_OTHER_ERROR, _("Object to save is not a valid vCard")));
+ g_propagate_error (error, EC_ERROR_EX (E_CLIENT_ERROR_INVALID_ARG, _("Object to save is not a valid vCard")));
}
g_free (vcard_string);
diff --git a/src/addressbook/libedata-book/e-book-meta-backend.c b/src/addressbook/libedata-book/e-book-meta-backend.c
index e1d0d39d2..28c1c1a53 100644
--- a/src/addressbook/libedata-book/e-book-meta-backend.c
+++ b/src/addressbook/libedata-book/e-book-meta-backend.c
@@ -128,6 +128,13 @@ static gboolean ebmb_save_contact_wrapper_sync (EBookMetaBackend *meta_backend,
gchar **out_new_extra,
GCancellable *cancellable,
GError **error);
+static gboolean ebmb_maybe_remove_from_cache (EBookMetaBackend *meta_backend,
+ EBookCache *book_cache,
+ ECacheOfflineFlag offline_flag,
+ const gchar *uid,
+ guint32 opflags,
+ GCancellable *cancellable,
+ GError **error);
static gboolean
ebmb_is_power_saver_enabled (void)
@@ -687,9 +694,24 @@ ebmb_upload_local_changes_sync (EBookMetaBackend *meta_backend,
success = e_book_cache_get_contact (book_cache, change->uid, FALSE, &contact, cancellable, error);
if (success) {
+ GError *local_error = NULL;
+
success = ebmb_save_contact_wrapper_sync (meta_backend, book_cache,
change->state == E_OFFLINE_STATE_LOCALLY_MODIFIED,
- conflict_resolution, contact, extra, opflags, change->uid, NULL, NULL, NULL, cancellable, error);
+ conflict_resolution, contact, extra, opflags, change->uid, NULL, NULL, NULL, cancellable, &local_error);
+
+ if (!success) {
+ if (g_error_matches (local_error, E_CLIENT_ERROR, E_CLIENT_ERROR_INVALID_ARG)) {
+ g_clear_error (&local_error);
+ success = TRUE;
+
+ if (!ebmb_maybe_remove_from_cache (meta_backend, book_cache, E_CACHE_IS_ONLINE, change->uid, 0, cancellable, NULL)) {
+ /* ignore any error here */
+ }
+ } else if (local_error) {
+ g_propagate_error (error, local_error);
+ }
+ }
}
g_clear_object (&contact);
@@ -700,7 +722,8 @@ ebmb_upload_local_changes_sync (EBookMetaBackend *meta_backend,
change->uid, extra, change->object, opflags, cancellable, &local_error);
if (!success) {
- if (g_error_matches (local_error, E_BOOK_CLIENT_ERROR, E_BOOK_CLIENT_ERROR_CONTACT_NOT_FOUND)) {
+ if (g_error_matches (local_error, E_BOOK_CLIENT_ERROR, E_BOOK_CLIENT_ERROR_CONTACT_NOT_FOUND) ||
+ g_error_matches (local_error, E_CLIENT_ERROR, E_CLIENT_ERROR_INVALID_ARG)) {
g_clear_error (&local_error);
success = TRUE;
} else if (local_error) {
diff --git a/src/calendar/libedata-cal/e-cal-meta-backend.c b/src/calendar/libedata-cal/e-cal-meta-backend.c
index 7e8afd34c..c03e42339 100644
--- a/src/calendar/libedata-cal/e-cal-meta-backend.c
+++ b/src/calendar/libedata-cal/e-cal-meta-backend.c
@@ -110,6 +110,13 @@ static ICalTimezone * (* ecmb_timezone_cache_parent_get_timezone) (ETimezoneCach
static GList * (* ecmb_timezone_cache_parent_list_timezones) (ETimezoneCache *cache);
/* Forward Declarations */
+static gboolean ecmb_maybe_remove_from_cache (ECalMetaBackend *meta_backend,
+ ECalCache *cal_cache,
+ ECacheOfflineFlag offline_flag,
+ const gchar *uid,
+ guint32 custom_flags,
+ GCancellable *cancellable,
+ GError **error);
static void e_cal_meta_backend_timezone_cache_init (ETimezoneCacheInterface *iface);
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (ECalMetaBackend, e_cal_meta_backend, E_TYPE_CAL_BACKEND_SYNC,
@@ -605,9 +612,24 @@ ecmb_upload_local_changes_sync (ECalMetaBackend *meta_backend,
success = e_cal_cache_get_components_by_uid (cal_cache, change->uid, &instances, cancellable, error);
if (success) {
+ GError *local_error = NULL;
+
success = ecmb_save_component_wrapper_sync (meta_backend, cal_cache,
change->state == E_OFFLINE_STATE_LOCALLY_MODIFIED,
- conflict_resolution, instances, extra, opflags, change->uid, NULL, NULL, NULL, cancellable, error);
+ conflict_resolution, instances, extra, opflags, change->uid, NULL, NULL, NULL, cancellable, &local_error);
+
+ if (!success) {
+ if (g_error_matches (local_error, E_CAL_CLIENT_ERROR, E_CAL_CLIENT_ERROR_INVALID_OBJECT)) {
+ g_clear_error (&local_error);
+ success = TRUE;
+
+ if (!ecmb_maybe_remove_from_cache (meta_backend, cal_cache, E_CACHE_IS_ONLINE, change->uid, 0, cancellable, NULL)) {
+ /* ignore any error here */
+ }
+ } else if (local_error) {
+ g_propagate_error (error, local_error);
+ }
+ }
}
g_slist_free_full (instances, g_object_unref);
@@ -618,7 +640,8 @@ ecmb_upload_local_changes_sync (ECalMetaBackend *meta_backend,
change->uid, extra, change->object, opflags, cancellable, &local_error);
if (!success) {
- if (g_error_matches (local_error, E_CAL_CLIENT_ERROR, E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND)) {
+ if (g_error_matches (local_error, E_CAL_CLIENT_ERROR, E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND) ||
+ g_error_matches (local_error, E_CAL_CLIENT_ERROR, E_CAL_CLIENT_ERROR_INVALID_OBJECT)) {
g_clear_error (&local_error);
success = TRUE;
} else if (local_error) {