Fix crashes with conflict dialog
authorFelix Weilbach <felix.weilbach@nextcloud.com>
Thu, 4 Mar 2021 14:31:58 +0000 (15:31 +0100)
committerFelix Weilbach (Rebase PR Action) <felix.weilbach@t-online.de>
Fri, 5 Mar 2021 11:32:44 +0000 (11:32 +0000)
When the client runs and a conflict gets detected, the sync engine runs
two times.

On the first run, the sync engine detects the conflict, marks the
file as a conflict and propagates that to the GUI. This leads to an
error notification with the original filename in the main dialog.

The sync engine runs then a second time. On this second run, the file
that originally caused the conflict is not anymore a conflict
file. Instead, the sync engine detects the conflicted copy and
propagates that file as a conflict to the GUI.

When opening the conflict dialog with the original file name (not the
conflicted copy) a crash happens. Usually, the two sync runs are really
fast, so the user does not notice the first notification. However, a
problem can occur if a conflict gets created while the client is not
running. Since then, the client does not do two sync runs. It does only
run once.

Signed-off-by: Felix Weilbach <felix.weilbach@nextcloud.com>
src/gui/tray/UserModel.cpp
src/gui/tray/UserModel.h
src/libsync/owncloudpropagator.cpp

index a175d3173b45e233796d5ef6e5c768b218c84fdb..682b8a393a72760e9fdfeafca7d564526410e881 100644 (file)
@@ -413,6 +413,22 @@ void User::slotAddError(const QString &folderAlias, const QString &message, Erro
     }
 }
 
+bool User::isValueableActivity(const Folder *folder, const SyncFileItemPtr &item) const
+{
+    // Check if we are adding it to the right account and if it is useful information (protocol errors)
+    const auto isDifferentAccount = folder->accountState() != _account.data();
+    const auto isConflictFromOriginalFile = item->_status == SyncFileItem::Conflict && !Utility::isConflictFile(item->_file);
+
+    if (isDifferentAccount) {
+        return false;
+    }
+    if (isConflictFromOriginalFile) {
+        return false;
+    }
+
+    return true;
+}
+
 void User::slotItemCompleted(const QString &folder, const SyncFileItemPtr &item)
 {
     auto folderInstance = FolderMan::instance()->folder(folder);
@@ -420,8 +436,7 @@ void User::slotItemCompleted(const QString &folder, const SyncFileItemPtr &item)
     if (!folderInstance)
         return;
 
-    // check if we are adding it to the right account and if it is useful information (protocol errors)
-    if (folderInstance->accountState() == _account.data()) {
+    if (isValueableActivity(folderInstance, item)) {
         qCWarning(lcActivity) << "Item " << item->_file << " retrieved resulted in " << item->_errorString;
 
         Activity activity;
index d9f99f1de77bde80d8b3da7774fa36ad18b7f581..535c9ad43223240209c66e1981c594bf55d64e29 100644 (file)
@@ -80,6 +80,8 @@ private:
     void connectPushNotifications() const;
     bool checkPushNotificationsAreReady() const;
 
+    bool isValueableActivity(const Folder *folder, const SyncFileItemPtr &item) const;
+
 private:
     AccountStatePtr _account;
     bool _isCurrentUser;
index 90ba4ea667b96599d35e66d6d165dfe9477f61b9..4c35a3956fa9b912a9b3b2afdb9f48216cf178c2 100644 (file)
@@ -742,13 +742,12 @@ bool OwncloudPropagator::createConflict(const SyncFileItemPtr &item,
             conflictItem->_size = item->_previousSize;
             emit newItem(conflictItem);
             composite->appendTask(conflictItem);
-        } else {
-            // Directories we can't process in one go. The next sync run
-            // will take care of uploading the conflict dir contents.
-            _anotherSyncNeeded = true;
         }
     }
 
+    // Need a new sync to detect the created copy of the conflicting file
+    _anotherSyncNeeded = true;
+
     return true;
 }