-
Notifications
You must be signed in to change notification settings - Fork 806
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix crash when opening conflict dialog #2948
Conversation
1313512
to
d226f64
Compare
Another solution to his problem as proposed by @allexzander would be to just run a second sync after a file conflict has been detected and don't propagate the first conflict error to the GUI. @er-vin I ping you because your input on this could be valuable :) |
This maybe a good idea as well. Maybe less invasive? I have a hard time to gauge this from the top of my head. Comes to mind that maybe it's the call to the dialog which should be fixed instead? I wonder if the call from socket api (so doesn't go at all through activity model) suffers from the same or a similar issue. |
d226f64
to
a5c4bae
Compare
I updated the pr to block the unnecessary activity and schedule a new sync after a conflicted copy gets created. |
a5c4bae
to
b00eb28
Compare
src/gui/tray/UserModel.cpp
Outdated
const auto isDifferentAccount = folder->accountState() != _account.data(); | ||
const auto isConflictFromOriginalFile = item->_status == SyncFileItem::Conflict && !Utility::isConflictFile(item->_file); | ||
|
||
if (isDifferentAccount) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We still have too many lines of code IMHO.
bool User::isValueableActivity(const Folder *folder, const SyncFileItemPtr &item) const
{
// activity for a different account - ignore it
if (!folder->accountState() != _account.data()) {
return false;
}
// first time conflict activity should be ignored until the next sync (fix conflict dialog crash issue)
if (item->_status == SyncFileItem::Conflict && !Utility::isConflictFile(item->_file) {
return false;
}
return true;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@allexzander I find it more descriptive with the variable names. Then it's even readable without the comments:) With you approach it's just one line less. However, I like your comments about the conditionals. I updated it and changed the wording a bit.
/rebase |
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>
a6ca9d4
to
63dbb90
Compare
AppImage file: Nextcloud-PR-2948-63dbb90bbd96d3169b6186fb7a37edddf3f00d3e-x86_64.AppImage |
void User::slotItemCompleted(const QString &folder, const SyncFileItemPtr &item) | ||
{ | ||
auto folderInstance = FolderMan::instance()->folder(folder); | ||
|
||
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)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ouch, this is subpar API naming, what is "valueable"? It will tell me nothing months from now. I think it was better not factoring this out in a method but instead store the result in two nicely named booleans and combine then in the if. Typically something like:
const auto isForUserAccount = folderInstance->accountState() == _account.data();
const auto isUnresolvableConflict = item->_status == SyncFileItem::Conflict && !Utility::isConflictFile(item->_file);
if (isForUserAccount && !isUnresolvableConflict) {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@er-vin @allexzander pr for that #2976
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@er-vin Sorry, we had to make it move forward.
No worries, I'm less available that's how it is. :-)
I must confess, I am not that nitpicky reviewer :)
Well, I know I put quite some nitpicks too, but there it was really more of a code smell. If something is not clearly named for some reason and one can't find a proper name for it... well something is fishy. ;-)
Note: This PR is a draft. It fixes the problem but probably needs some polishing. I first wanted to hear your thoughts about this problem, my findings and my proposed solution before I investigate further.
Now to the actual problem:
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.
Steps to reproduce the original Issue on master:
Signed-off-by: Felix Weilbach felix.weilbach@nextcloud.com