mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-25 14:36:01 +03:00
Merge pull request #5768 from nextcloud/bugfix/errorMessageConnectionIssues
display subject when we have sync issues like network errors
This commit is contained in:
commit
3e4dc5d2cd
30 changed files with 313 additions and 190 deletions
|
@ -29,7 +29,7 @@ steps:
|
|||
- cd /drone/build
|
||||
- useradd -m -s /bin/bash test
|
||||
- chown -R test:test .
|
||||
- su -c 'ASAN_OPTIONS=detect_leaks=0 xvfb-run ctest --output-on-failure' test
|
||||
- su -c 'ASAN_OPTIONS=detect_odr_violation=0,detect_leaks=0 xvfb-run ctest --output-on-failure' test
|
||||
|
||||
services:
|
||||
- name: server
|
||||
|
@ -97,7 +97,7 @@ steps:
|
|||
- cd /drone/build
|
||||
- useradd -m -s /bin/bash test
|
||||
- chown -R test:test .
|
||||
- su -c 'ASAN_OPTIONS=detect_leaks=0 xvfb-run ctest --output-on-failure' test
|
||||
- su -c 'ASAN_OPTIONS=detect_odr_violation=0,detect_leaks=0 xvfb-run ctest --output-on-failure' test
|
||||
|
||||
services:
|
||||
- name: server
|
||||
|
|
2
.github/workflows/sonarcloud.yml
vendored
2
.github/workflows/sonarcloud.yml
vendored
|
@ -8,7 +8,7 @@ on:
|
|||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
container: ghcr.io/nextcloud/continuous-integration-client:client-5.15-11
|
||||
env:
|
||||
SONAR_SERVER_URL: "https://sonarcloud.io"
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
namespace OCC {
|
||||
|
||||
namespace PinStateEnums {
|
||||
OCSYNC_EXPORT Q_NAMESPACE
|
||||
|
||||
/** Determines whether items should be available locally permanently or not
|
||||
|
@ -126,8 +125,6 @@ enum class VfsItemAvailability {
|
|||
OnlineOnly = 4,
|
||||
};
|
||||
Q_ENUM_NS(VfsItemAvailability)
|
||||
}
|
||||
using namespace PinStateEnums;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -438,7 +438,7 @@ void EditLocallyJob::showErrorNotification(const QString &message, const QString
|
|||
});
|
||||
|
||||
if (foundFolder != folderMap.cend()) {
|
||||
emit (*foundFolder)->syncEngine().addErrorToGui(SyncFileItem::SoftError, message, informativeText);
|
||||
emit (*foundFolder)->syncEngine().addErrorToGui(SyncFileItem::SoftError, message, informativeText, OCC::ErrorCategory::GenericError);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -890,7 +890,7 @@ void Folder::startSync(const QStringList &pathList)
|
|||
_fileLog->start(path());
|
||||
|
||||
if (!reloadExcludes()) {
|
||||
slotSyncError(tr("Could not read system exclude file"));
|
||||
slotSyncError(tr("Could not read system exclude file"), ErrorCategory::GenericError);
|
||||
QMetaObject::invokeMethod(this, "slotSyncFinished", Qt::QueuedConnection, Q_ARG(bool, false));
|
||||
return;
|
||||
}
|
||||
|
@ -1005,9 +1005,9 @@ void Folder::slotSyncError(const QString &message, ErrorCategory category)
|
|||
}
|
||||
}
|
||||
|
||||
void Folder::slotAddErrorToGui(SyncFileItem::Status status, const QString &errorMessage, const QString &subject)
|
||||
void Folder::slotAddErrorToGui(SyncFileItem::Status status, const QString &errorMessage, const QString &subject, ErrorCategory category)
|
||||
{
|
||||
emit ProgressDispatcher::instance()->addErrorToGui(alias(), status, errorMessage, subject);
|
||||
emit ProgressDispatcher::instance()->addErrorToGui(alias(), status, errorMessage, subject, category);
|
||||
}
|
||||
|
||||
void Folder::slotSyncStarted()
|
||||
|
@ -1128,7 +1128,7 @@ void Folder::slotTransmissionProgress(const ProgressInfo &pi)
|
|||
}
|
||||
|
||||
// a item is completed: count the errors and forward to the ProgressDispatcher
|
||||
void Folder::slotItemCompleted(const SyncFileItemPtr &item)
|
||||
void Folder::slotItemCompleted(const SyncFileItemPtr &item, ErrorCategory errorCategory)
|
||||
{
|
||||
if (item->_instruction == CSYNC_INSTRUCTION_NONE || item->_instruction == CSYNC_INSTRUCTION_UPDATE_METADATA) {
|
||||
// We only care about the updates that deserve to be shown in the UI
|
||||
|
@ -1144,7 +1144,7 @@ void Folder::slotItemCompleted(const SyncFileItemPtr &item)
|
|||
_syncResult.processCompletedItem(item);
|
||||
|
||||
_fileLog->logItem(*item);
|
||||
emit ProgressDispatcher::instance()->itemCompleted(alias(), item);
|
||||
emit ProgressDispatcher::instance()->itemCompleted(alias(), item, errorCategory);
|
||||
}
|
||||
|
||||
void Folder::slotNewBigFolderDiscovered(const QString &newF, bool isExternal)
|
||||
|
|
|
@ -388,12 +388,12 @@ private slots:
|
|||
|
||||
/** Adds a error message that's not tied to a specific item.
|
||||
*/
|
||||
void slotSyncError(const QString &message, OCC::ErrorCategory category = OCC::ErrorCategory::Normal);
|
||||
void slotSyncError(const QString &message, OCC::ErrorCategory category);
|
||||
|
||||
void slotAddErrorToGui(OCC::SyncFileItem::Status status, const QString &errorMessage, const QString &subject = {});
|
||||
void slotAddErrorToGui(OCC::SyncFileItem::Status status, const QString &errorMessage, const QString &subject, OCC::ErrorCategory category);
|
||||
|
||||
void slotTransmissionProgress(const OCC::ProgressInfo &pi);
|
||||
void slotItemCompleted(const OCC::SyncFileItemPtr &);
|
||||
void slotItemCompleted(const OCC::SyncFileItemPtr &, OCC::ErrorCategory errorCategory);
|
||||
|
||||
void slotRunEtagJob();
|
||||
void etagRetrieved(const QByteArray &, const QDateTime &tp);
|
||||
|
|
|
@ -221,7 +221,7 @@ RowLayout {
|
|||
Layout.fillHeight: true
|
||||
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
|
||||
|
||||
text: (root.activityData.type === "Sync") ? root.activityData.displayPath
|
||||
text: (root.activityData.type === "Sync") ? root.activityData.subject
|
||||
: (root.activityData.type === "File") ? root.activityData.subject
|
||||
: (root.activityData.type === "Notification") ? root.activityData.message
|
||||
: ""
|
||||
|
|
|
@ -556,11 +556,15 @@ void ActivityListModel::addEntriesToActivityList(const ActivityList &activityLis
|
|||
setHasSyncConflicts(conflictsFound);
|
||||
}
|
||||
|
||||
void ActivityListModel::addErrorToActivityList(const Activity &activity)
|
||||
void ActivityListModel::addErrorToActivityList(const Activity &activity, const ErrorType type)
|
||||
{
|
||||
qCInfo(lcActivity) << "Error successfully added to the notification list: " << activity._message << activity._subject << activity._syncResultStatus << activity._syncFileItemStatus;
|
||||
addEntriesToActivityList({activity});
|
||||
_notificationErrorsLists.prepend(activity);
|
||||
qCInfo(lcActivity) << "Error successfully added to the notification list: " << type << activity._message << activity._subject << activity._syncResultStatus << activity._syncFileItemStatus;
|
||||
auto modifiedActivity = activity;
|
||||
if (type == ErrorType::NetworkError) {
|
||||
modifiedActivity._subject = tr("Network error occurred: client will retry syncing.");
|
||||
}
|
||||
addEntriesToActivityList({modifiedActivity});
|
||||
_notificationErrorsLists.prepend(modifiedActivity);
|
||||
}
|
||||
|
||||
void ActivityListModel::addIgnoredFileToList(const Activity &newActivity)
|
||||
|
|
|
@ -82,6 +82,12 @@ public:
|
|||
};
|
||||
Q_ENUM(DataRole)
|
||||
|
||||
enum class ErrorType {
|
||||
SyncError,
|
||||
NetworkError,
|
||||
};
|
||||
Q_ENUM(ErrorType)
|
||||
|
||||
explicit ActivityListModel(QObject *parent = nullptr);
|
||||
|
||||
explicit ActivityListModel(AccountState *accountState,
|
||||
|
@ -122,7 +128,7 @@ public slots:
|
|||
void slotTriggerDismiss(const int activityIndex);
|
||||
|
||||
void addNotificationToActivityList(const OCC::Activity &activity);
|
||||
void addErrorToActivityList(const OCC::Activity &activity);
|
||||
void addErrorToActivityList(const OCC::Activity &activity, const ErrorType type);
|
||||
void addIgnoredFileToList(const OCC::Activity &newActivity);
|
||||
void addSyncFileItemToActivityList(const OCC::Activity &activity);
|
||||
void removeActivityFromActivityList(int row);
|
||||
|
|
|
@ -627,12 +627,27 @@ void User::slotAddError(const QString &folderAlias, const QString &message, Erro
|
|||
activity._links.append(link);
|
||||
}
|
||||
|
||||
auto errorType = ActivityListModel::ErrorType::SyncError;
|
||||
// add 'other errors' to activity list
|
||||
_activityModel->addErrorToActivityList(activity);
|
||||
switch (category) {
|
||||
case ErrorCategory::GenericError:
|
||||
errorType = ActivityListModel::ErrorType::SyncError;
|
||||
break;
|
||||
case ErrorCategory::InsufficientRemoteStorage:
|
||||
errorType = ActivityListModel::ErrorType::SyncError;
|
||||
break;
|
||||
case ErrorCategory::NetworkError:
|
||||
errorType = ActivityListModel::ErrorType::NetworkError;
|
||||
break;
|
||||
case ErrorCategory::NoError:
|
||||
break;
|
||||
}
|
||||
|
||||
_activityModel->addErrorToActivityList(activity, errorType);
|
||||
}
|
||||
}
|
||||
|
||||
void User::slotAddErrorToGui(const QString &folderAlias, SyncFileItem::Status status, const QString &errorMessage, const QString &subject)
|
||||
void User::slotAddErrorToGui(const QString &folderAlias, const SyncFileItem::Status status, const QString &errorMessage, const QString &subject, const ErrorCategory category)
|
||||
{
|
||||
const auto folderInstance = FolderMan::instance()->folder(folderAlias);
|
||||
if (!folderInstance) {
|
||||
|
@ -668,7 +683,24 @@ void User::slotAddErrorToGui(const QString &folderAlias, SyncFileItem::Status st
|
|||
activity._id = -static_cast<int>(qHash(activity._subject + activity._message));
|
||||
|
||||
// add 'other errors' to activity list
|
||||
_activityModel->addErrorToActivityList(activity);
|
||||
auto errorType = ActivityListModel::ErrorType::SyncError;
|
||||
switch (category)
|
||||
{
|
||||
case ErrorCategory::GenericError:
|
||||
errorType = ActivityListModel::ErrorType::SyncError;
|
||||
break;
|
||||
case ErrorCategory::InsufficientRemoteStorage:
|
||||
errorType = ActivityListModel::ErrorType::SyncError;
|
||||
break;
|
||||
case ErrorCategory::NetworkError:
|
||||
errorType = ActivityListModel::ErrorType::NetworkError;
|
||||
break;
|
||||
case ErrorCategory::NoError:
|
||||
errorType = {};
|
||||
break;
|
||||
}
|
||||
|
||||
_activityModel->addErrorToActivityList(activity, errorType);
|
||||
|
||||
showDesktopNotification(activity);
|
||||
|
||||
|
@ -787,7 +819,7 @@ void User::processCompletedSyncItem(const Folder *folder, const SyncFileItemPtr
|
|||
|
||||
activity._links = {buttonActivityLink};
|
||||
}
|
||||
_activityModel->addErrorToActivityList(activity);
|
||||
_activityModel->addErrorToActivityList(activity, ActivityListModel::ErrorType::SyncError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@ public slots:
|
|||
void slotItemCompleted(const QString &folder, const OCC::SyncFileItemPtr &item);
|
||||
void slotProgressInfo(const QString &folder, const OCC::ProgressInfo &progress);
|
||||
void slotAddError(const QString &folderAlias, const QString &message, OCC::ErrorCategory category);
|
||||
void slotAddErrorToGui(const QString &folderAlias, OCC::SyncFileItem::Status status, const QString &errorMessage, const QString &subject = {});
|
||||
void slotAddErrorToGui(const QString &folderAlias, const OCC::SyncFileItem::Status status, const QString &errorMessage, const QString &subject, const ErrorCategory category);
|
||||
void slotNotificationRequestFinished(int statusCode);
|
||||
void slotNotifyNetworkError(QNetworkReply *reply);
|
||||
void slotEndNotificationRequest(int replyCode);
|
||||
|
|
|
@ -120,7 +120,7 @@ void BulkPropagatorJob::startUploadFile(SyncFileItemPtr item, UploadFileInfo fil
|
|||
|
||||
// Check if the specific file can be accessed
|
||||
if (propagator()->hasCaseClashAccessibilityProblem(fileToUpload._file)) {
|
||||
done(item, SyncFileItem::NormalError, tr("File %1 cannot be uploaded because another file with the same name, differing only in case, exists").arg(QDir::toNativeSeparators(item->_file)));
|
||||
done(item, SyncFileItem::NormalError, tr("File %1 cannot be uploaded because another file with the same name, differing only in case, exists").arg(QDir::toNativeSeparators(item->_file)), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -160,7 +160,7 @@ void BulkPropagatorJob::doStartUpload(SyncFileItemPtr item,
|
|||
const auto renameSuccess = QFile::rename(originalFilePathAbsolute, newFilePathAbsolute);
|
||||
|
||||
if (!renameSuccess) {
|
||||
done(item, SyncFileItem::NormalError, "File contains trailing spaces and couldn't be renamed");
|
||||
done(item, SyncFileItem::NormalError, "File contains trailing spaces and couldn't be renamed", ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -172,7 +172,7 @@ void BulkPropagatorJob::doStartUpload(SyncFileItemPtr item,
|
|||
item->_modtime = FileSystem::getModTime(newFilePathAbsolute);
|
||||
if (item->_modtime <= 0) {
|
||||
_pendingChecksumFiles.remove(item->_file);
|
||||
slotOnErrorStartFolderUnlock(item, SyncFileItem::NormalError, tr("File %1 has invalid modified time. Do not upload to the server.").arg(QDir::toNativeSeparators(item->_file)));
|
||||
slotOnErrorStartFolderUnlock(item, SyncFileItem::NormalError, tr("File %1 has invalid modified time. Do not upload to the server.").arg(QDir::toNativeSeparators(item->_file)), ErrorCategory::GenericError);
|
||||
checkPropagationIsDone();
|
||||
return;
|
||||
}
|
||||
|
@ -293,7 +293,7 @@ void BulkPropagatorJob::slotStartUpload(SyncFileItemPtr item,
|
|||
|
||||
if (!FileSystem::fileExists(fullFilePath)) {
|
||||
_pendingChecksumFiles.remove(item->_file);
|
||||
slotOnErrorStartFolderUnlock(item, SyncFileItem::SoftError, tr("File Removed (start upload) %1").arg(fullFilePath));
|
||||
slotOnErrorStartFolderUnlock(item, SyncFileItem::SoftError, tr("File Removed (start upload) %1").arg(fullFilePath), ErrorCategory::GenericError);
|
||||
checkPropagationIsDone();
|
||||
return;
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ void BulkPropagatorJob::slotStartUpload(SyncFileItemPtr item,
|
|||
item->_modtime = FileSystem::getModTime(originalFilePath);
|
||||
if (item->_modtime <= 0) {
|
||||
_pendingChecksumFiles.remove(item->_file);
|
||||
slotOnErrorStartFolderUnlock(item, SyncFileItem::NormalError, tr("File %1 has invalid modification time. Do not upload to the server.").arg(QDir::toNativeSeparators(item->_file)));
|
||||
slotOnErrorStartFolderUnlock(item, SyncFileItem::NormalError, tr("File %1 has invalid modification time. Do not upload to the server.").arg(QDir::toNativeSeparators(item->_file)), ErrorCategory::GenericError);
|
||||
checkPropagationIsDone();
|
||||
return;
|
||||
}
|
||||
|
@ -317,7 +317,7 @@ void BulkPropagatorJob::slotStartUpload(SyncFileItemPtr item,
|
|||
<< "prevModtime" << prevModtime
|
||||
<< "Curr" << item->_modtime;
|
||||
|
||||
slotOnErrorStartFolderUnlock(item, SyncFileItem::SoftError, tr("Local file changed during syncing. It will be resumed."));
|
||||
slotOnErrorStartFolderUnlock(item, SyncFileItem::SoftError, tr("Local file changed during syncing. It will be resumed."), ErrorCategory::GenericError);
|
||||
checkPropagationIsDone();
|
||||
return;
|
||||
}
|
||||
|
@ -331,7 +331,7 @@ void BulkPropagatorJob::slotStartUpload(SyncFileItemPtr item,
|
|||
if (fileIsStillChanging(*item)) {
|
||||
propagator()->_anotherSyncNeeded = true;
|
||||
_pendingChecksumFiles.remove(item->_file);
|
||||
slotOnErrorStartFolderUnlock(item, SyncFileItem::SoftError, tr("Local file changed during sync."));
|
||||
slotOnErrorStartFolderUnlock(item, SyncFileItem::SoftError, tr("Local file changed during sync."), ErrorCategory::GenericError);
|
||||
checkPropagationIsDone();
|
||||
return;
|
||||
}
|
||||
|
@ -340,11 +340,12 @@ void BulkPropagatorJob::slotStartUpload(SyncFileItemPtr item,
|
|||
}
|
||||
|
||||
void BulkPropagatorJob::slotOnErrorStartFolderUnlock(SyncFileItemPtr item,
|
||||
SyncFileItem::Status status,
|
||||
const QString &errorString)
|
||||
const SyncFileItem::Status status,
|
||||
const QString &errorString,
|
||||
const ErrorCategory errorCategory)
|
||||
{
|
||||
qCInfo(lcBulkPropagatorJob()) << status << errorString;
|
||||
done(item, status, errorString);
|
||||
qCInfo(lcBulkPropagatorJob()) << status << errorString << errorCategory;
|
||||
done(item, status, errorString, errorCategory);
|
||||
}
|
||||
|
||||
void BulkPropagatorJob::slotPutFinishedOneFile(const BulkUploadItem &singleFile,
|
||||
|
@ -473,10 +474,10 @@ void BulkPropagatorJob::finalizeOneFile(const BulkUploadItem &oneFile)
|
|||
// Update the database entry
|
||||
const auto result = propagator()->updateMetadata(*oneFile._item);
|
||||
if (!result) {
|
||||
done(oneFile._item, SyncFileItem::FatalError, tr("Error updating metadata: %1").arg(result.error()));
|
||||
done(oneFile._item, SyncFileItem::FatalError, tr("Error updating metadata: %1").arg(result.error()), ErrorCategory::GenericError);
|
||||
return;
|
||||
} else if (*result == Vfs::ConvertToPlaceholderResult::Locked) {
|
||||
done(oneFile._item, SyncFileItem::SoftError, tr("The file %1 is currently in use").arg(oneFile._item->_file));
|
||||
done(oneFile._item, SyncFileItem::SoftError, tr("The file %1 is currently in use").arg(oneFile._item->_file), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -511,7 +512,7 @@ void BulkPropagatorJob::finalize(const QJsonObject &fullReply)
|
|||
finalizeOneFile(singleFile);
|
||||
}
|
||||
|
||||
done(singleFile._item, singleFile._item->_status, {});
|
||||
done(singleFile._item, singleFile._item->_status, {}, ErrorCategory::GenericError);
|
||||
|
||||
singleFileIt = _filesToUpload.erase(singleFileIt);
|
||||
}
|
||||
|
@ -520,8 +521,9 @@ void BulkPropagatorJob::finalize(const QJsonObject &fullReply)
|
|||
}
|
||||
|
||||
void BulkPropagatorJob::done(SyncFileItemPtr item,
|
||||
SyncFileItem::Status status,
|
||||
const QString &errorString)
|
||||
const SyncFileItem::Status status,
|
||||
const QString &errorString,
|
||||
const ErrorCategory category)
|
||||
{
|
||||
item->_status = status;
|
||||
item->_errorString = errorString;
|
||||
|
@ -548,7 +550,7 @@ void BulkPropagatorJob::done(SyncFileItemPtr item,
|
|||
|
||||
handleJobDoneErrors(item, status);
|
||||
|
||||
emit propagator()->itemCompleted(item);
|
||||
emit propagator()->itemCompleted(item, category);
|
||||
}
|
||||
|
||||
QMap<QByteArray, QByteArray> BulkPropagatorJob::headers(SyncFileItemPtr item) const
|
||||
|
@ -606,7 +608,7 @@ void BulkPropagatorJob::abortWithError(SyncFileItemPtr item,
|
|||
const QString &error)
|
||||
{
|
||||
abort(AbortType::Synchronous);
|
||||
done(item, status, error);
|
||||
done(item, status, error, ErrorCategory::GenericError);
|
||||
}
|
||||
|
||||
void BulkPropagatorJob::checkResettingErrors(SyncFileItemPtr item) const
|
||||
|
|
|
@ -81,8 +81,9 @@ private slots:
|
|||
|
||||
// invoked on internal error to unlock a folder and faile
|
||||
void slotOnErrorStartFolderUnlock(OCC::SyncFileItemPtr item,
|
||||
OCC::SyncFileItem::Status status,
|
||||
const QString &errorString);
|
||||
const OCC::SyncFileItem::Status status,
|
||||
const QString &errorString,
|
||||
const OCC::ErrorCategory errorCategory);
|
||||
|
||||
void slotPutFinished();
|
||||
|
||||
|
@ -107,8 +108,9 @@ private:
|
|||
const QJsonObject &fullReplyObject);
|
||||
|
||||
void done(SyncFileItemPtr item,
|
||||
SyncFileItem::Status status,
|
||||
const QString &errorString);
|
||||
const SyncFileItem::Status status,
|
||||
const QString &errorString,
|
||||
const ErrorCategory category);
|
||||
|
||||
/** Bases headers that need to be sent on the PUT, or in the MOVE for chunking-ng */
|
||||
[[nodiscard]] QMap<QByteArray, QByteArray> headers(SyncFileItemPtr item) const;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "common/syncjournaldb.h"
|
||||
#include "filesystem.h"
|
||||
#include "syncfileitem.h"
|
||||
#include "progressdispatcher.h"
|
||||
#include <QDebug>
|
||||
#include <algorithm>
|
||||
#include <QEventLoop>
|
||||
|
@ -964,7 +965,7 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo(
|
|||
// Not locally, not on the server. The entry is stale!
|
||||
qCInfo(lcDisco) << "Stale DB entry";
|
||||
if (!_discoveryData->_statedb->deleteFileRecord(path._original, true)) {
|
||||
emit _discoveryData->fatalError(tr("Error while deleting file record %1 from the database").arg(path._original));
|
||||
emit _discoveryData->fatalError(tr("Error while deleting file record %1 from the database").arg(path._original), ErrorCategory::GenericError);
|
||||
qCWarning(lcDisco) << "Failed to delete a file record from the local DB" << path._original;
|
||||
}
|
||||
return;
|
||||
|
@ -1178,7 +1179,7 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo(
|
|||
// either correct availability, or a result with error if the folder is new or otherwise has no availability set yet
|
||||
const auto folderPlaceHolderAvailability = localEntry.isDirectory ? _discoveryData->_syncOptions._vfs->availability(path._local) : Vfs::AvailabilityResult(Vfs::AvailabilityError::NoSuchItem);
|
||||
|
||||
const auto folderPinState = localEntry.isDirectory ? _discoveryData->_syncOptions._vfs->pinState(path._local) : Optional<PinStateEnums::PinState>(PinState::Unspecified);
|
||||
const auto folderPinState = localEntry.isDirectory ? _discoveryData->_syncOptions._vfs->pinState(path._local) : Optional<PinState>(PinState::Unspecified);
|
||||
|
||||
if (!isFilePlaceHolder && !folderPlaceHolderAvailability.isValid() && !folderPinState.isValid()) {
|
||||
// not a file placeholder and not a synced folder placeholder (new local folder)
|
||||
|
@ -1214,10 +1215,10 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo(
|
|||
if (isFolderPinStateOnlineOnly && folderPinState.isValid()) {
|
||||
qCInfo(lcDisco) << "*folderPinState:" << *folderPinState;
|
||||
}
|
||||
emit _discoveryData->addErrorToGui(SyncFileItem::SoftError, tr("Conflict when uploading a folder. It's going to get cleared!"), path._local);
|
||||
emit _discoveryData->addErrorToGui(SyncFileItem::SoftError, tr("Conflict when uploading a folder. It's going to get cleared!"), path._local, ErrorCategory::GenericError);
|
||||
} else {
|
||||
qCInfo(lcDisco) << "Wiping virtual file without db entry for" << path._local;
|
||||
emit _discoveryData->addErrorToGui(SyncFileItem::SoftError, tr("Conflict when uploading a file. It's going to get removed!"), path._local);
|
||||
emit _discoveryData->addErrorToGui(SyncFileItem::SoftError, tr("Conflict when uploading a file. It's going to get removed!"), path._local, ErrorCategory::GenericError);
|
||||
}
|
||||
item->_instruction = CSYNC_INSTRUCTION_REMOVE;
|
||||
item->_direction = SyncFileItem::Down;
|
||||
|
@ -1813,7 +1814,7 @@ int ProcessDirectoryJob::processSubJobs(int nbJobs)
|
|||
|
||||
void ProcessDirectoryJob::dbError()
|
||||
{
|
||||
emit _discoveryData->fatalError(tr("Error while reading the database"));
|
||||
emit _discoveryData->fatalError(tr("Error while reading the database"), ErrorCategory::GenericError);
|
||||
}
|
||||
|
||||
void ProcessDirectoryJob::addVirtualFileSuffix(QString &str) const
|
||||
|
@ -1880,7 +1881,7 @@ DiscoverySingleDirectoryJob *ProcessDirectoryJob::startAsyncServerQuery()
|
|||
} else {
|
||||
// Fatal for the root job since it has no SyncFileItem, or for the network errors
|
||||
emit _discoveryData->fatalError(tr("Server replied with an error while reading directory \"%1\" : %2")
|
||||
.arg(_currentFolder._server, results.error().message));
|
||||
.arg(_currentFolder._server, results.error().message), ErrorCategory::NetworkError);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1910,7 +1911,7 @@ void ProcessDirectoryJob::startAsyncLocalQuery()
|
|||
if (_serverJob)
|
||||
_serverJob->abort();
|
||||
|
||||
emit _discoveryData->fatalError(msg);
|
||||
emit _discoveryData->fatalError(msg, ErrorCategory::NetworkError);
|
||||
});
|
||||
|
||||
connect(localJob, &DiscoverySingleLocalDirectoryJob::finishedNonFatalError, this, [this](const QString &msg) {
|
||||
|
@ -1923,7 +1924,7 @@ void ProcessDirectoryJob::startAsyncLocalQuery()
|
|||
emit this->finished();
|
||||
} else {
|
||||
// Fatal for the root job since it has no SyncFileItem
|
||||
emit _discoveryData->fatalError(msg);
|
||||
emit _discoveryData->fatalError(msg, ErrorCategory::GenericError);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "discoveryphase.h"
|
||||
#include "discovery.h"
|
||||
#include "helpers.h"
|
||||
#include "progressdispatcher.h"
|
||||
|
||||
#include "account.h"
|
||||
#include "clientsideencryptionjobs.h"
|
||||
|
@ -187,8 +188,8 @@ QPair<bool, QByteArray> DiscoveryPhase::findAndCancelDeletedJob(const QString &o
|
|||
qCWarning(lcDiscovery) << "(*it)->_type" << (*it)->_type;
|
||||
qCWarning(lcDiscovery) << "(*it)->_isRestoration " << (*it)->_isRestoration;
|
||||
Q_ASSERT(false);
|
||||
emit addErrorToGui(SyncFileItem::Status::FatalError, tr("Error while canceling deletion of a file"), originalPath);
|
||||
emit fatalError(tr("Error while canceling deletion of %1").arg(originalPath));
|
||||
emit addErrorToGui(SyncFileItem::Status::FatalError, tr("Error while canceling deletion of a file"), originalPath, ErrorCategory::GenericError);
|
||||
emit fatalError(tr("Error while canceling deletion of %1").arg(originalPath), ErrorCategory::GenericError);
|
||||
}
|
||||
(*it)->_instruction = CSYNC_INSTRUCTION_NONE;
|
||||
result = true;
|
||||
|
|
|
@ -51,6 +51,8 @@ class Account;
|
|||
class SyncJournalDb;
|
||||
class ProcessDirectoryJob;
|
||||
|
||||
enum class ErrorCategory;
|
||||
|
||||
/**
|
||||
* Represent all the meta-data about a file in the server
|
||||
*/
|
||||
|
@ -307,7 +309,7 @@ public:
|
|||
QStringList _listExclusiveFiles;
|
||||
|
||||
signals:
|
||||
void fatalError(const QString &errorString);
|
||||
void fatalError(const QString &errorString, const OCC::ErrorCategory errorCategory);
|
||||
void itemDiscovered(const OCC::SyncFileItemPtr &item);
|
||||
void finished();
|
||||
|
||||
|
@ -320,7 +322,7 @@ signals:
|
|||
*/
|
||||
void silentlyExcluded(const QString &folderPath);
|
||||
|
||||
void addErrorToGui(SyncFileItem::Status status, const QString &errorMessage, const QString &subject);
|
||||
void addErrorToGui(const SyncFileItem::Status status, const QString &errorMessage, const QString &subject, const OCC::ErrorCategory category);
|
||||
};
|
||||
|
||||
/// Implementation of DiscoveryPhase::adjustRenamedPath
|
||||
|
|
|
@ -221,7 +221,7 @@ void blacklistUpdate(SyncJournalDb *journal, SyncFileItem &item)
|
|||
}
|
||||
}
|
||||
|
||||
void PropagateItemJob::done(SyncFileItem::Status statusArg, const QString &errorString)
|
||||
void PropagateItemJob::done(const SyncFileItem::Status statusArg, const QString &errorString, const ErrorCategory category)
|
||||
{
|
||||
// Duplicate calls to done() are a logic error
|
||||
ENFORCE(_state != Finished);
|
||||
|
@ -283,7 +283,7 @@ void PropagateItemJob::done(SyncFileItem::Status statusArg, const QString &error
|
|||
qCWarning(lcPropagator) << "Could not complete propagation of" << _item->destination() << "by" << this << "with status" << _item->_status << "and error:" << _item->_errorString;
|
||||
else
|
||||
qCInfo(lcPropagator) << "Completed propagation of" << _item->destination() << "by" << this << "with status" << _item->_status;
|
||||
emit propagator()->itemCompleted(_item);
|
||||
emit propagator()->itemCompleted(_item, category);
|
||||
emit finished(_item->_status);
|
||||
|
||||
if (_item->_status == SyncFileItem::FatalError) {
|
||||
|
@ -302,9 +302,9 @@ void PropagateItemJob::slotRestoreJobFinished(SyncFileItem::Status status)
|
|||
|
||||
if (status == SyncFileItem::Success || status == SyncFileItem::Conflict
|
||||
|| status == SyncFileItem::Restoration) {
|
||||
done(SyncFileItem::SoftError, msg);
|
||||
done(SyncFileItem::SoftError, msg, ErrorCategory::GenericError);
|
||||
} else {
|
||||
done(status, tr("A file or folder was removed from a read only share, but restoring failed: %1").arg(msg));
|
||||
done(status, tr("A file or folder was removed from a read only share, but restoring failed: %1").arg(msg), ErrorCategory::GenericError);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -661,7 +661,7 @@ void OwncloudPropagator::startDirectoryPropagation(const SyncFileItemPtr &item,
|
|||
item->_instruction = CSyncEnums::CSYNC_INSTRUCTION_ERROR;
|
||||
item->_errorString = tr("Error with the metadata. Getting unexpected metadata format.");
|
||||
item->_status = SyncFileItem::NormalError;
|
||||
emit itemCompleted(item);
|
||||
emit itemCompleted(item, OCC::ErrorCategory::GenericError);
|
||||
} else {
|
||||
directoryPropagationJob->appendJob(new UpdateFileDropMetadataJob(this, item->_file));
|
||||
item->_instruction = CSYNC_INSTRUCTION_NONE;
|
||||
|
@ -1087,6 +1087,56 @@ OwncloudPropagator *PropagatorJob::propagator() const
|
|||
return qobject_cast<OwncloudPropagator *>(parent());
|
||||
}
|
||||
|
||||
ErrorCategory PropagatorJob::errorCategoryFromNetworkError(const QNetworkReply::NetworkError error)
|
||||
{
|
||||
auto result = ErrorCategory::NoError;
|
||||
switch (error)
|
||||
{
|
||||
case QNetworkReply::NoError:
|
||||
result = ErrorCategory::NoError;
|
||||
break;
|
||||
case QNetworkReply::TemporaryNetworkFailureError:
|
||||
case QNetworkReply::RemoteHostClosedError:
|
||||
result = ErrorCategory::NetworkError;
|
||||
break;
|
||||
case QNetworkReply::ConnectionRefusedError:
|
||||
case QNetworkReply::HostNotFoundError:
|
||||
case QNetworkReply::TimeoutError:
|
||||
case QNetworkReply::OperationCanceledError:
|
||||
case QNetworkReply::SslHandshakeFailedError:
|
||||
case QNetworkReply::NetworkSessionFailedError:
|
||||
case QNetworkReply::BackgroundRequestNotAllowedError:
|
||||
case QNetworkReply::TooManyRedirectsError:
|
||||
case QNetworkReply::InsecureRedirectError:
|
||||
case QNetworkReply::UnknownNetworkError:
|
||||
case QNetworkReply::ProxyConnectionRefusedError:
|
||||
case QNetworkReply::ProxyConnectionClosedError:
|
||||
case QNetworkReply::ProxyNotFoundError:
|
||||
case QNetworkReply::ProxyTimeoutError:
|
||||
case QNetworkReply::ProxyAuthenticationRequiredError:
|
||||
case QNetworkReply::UnknownProxyError:
|
||||
case QNetworkReply::ContentAccessDenied:
|
||||
case QNetworkReply::ContentOperationNotPermittedError:
|
||||
case QNetworkReply::ContentNotFoundError:
|
||||
case QNetworkReply::AuthenticationRequiredError:
|
||||
case QNetworkReply::ContentReSendError:
|
||||
case QNetworkReply::ContentConflictError:
|
||||
case QNetworkReply::ContentGoneError:
|
||||
case QNetworkReply::UnknownContentError:
|
||||
case QNetworkReply::ProtocolUnknownError:
|
||||
case QNetworkReply::ProtocolInvalidOperationError:
|
||||
case QNetworkReply::ProtocolFailure:
|
||||
case QNetworkReply::InternalServerError:
|
||||
case QNetworkReply::OperationNotImplementedError:
|
||||
case QNetworkReply::ServiceUnavailableError:
|
||||
case QNetworkReply::UnknownServerError:
|
||||
result = ErrorCategory::GenericError;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ================================================================================
|
||||
|
||||
PropagatorJob::JobParallelism PropagatorCompositeJob::parallelism() const
|
||||
|
@ -1521,7 +1571,7 @@ void CleanupPollsJob::slotPollFinished()
|
|||
auto *job = qobject_cast<PollJob *>(sender());
|
||||
ASSERT(job);
|
||||
if (job->_item->_status == SyncFileItem::FatalError) {
|
||||
emit aborted(job->_item->_errorString);
|
||||
emit aborted(job->_item->_errorString, ErrorCategory::GenericError);
|
||||
deleteLater();
|
||||
return;
|
||||
} else if (job->_item->_status != SyncFileItem::Success) {
|
||||
|
@ -1531,7 +1581,7 @@ void CleanupPollsJob::slotPollFinished()
|
|||
qCWarning(lcCleanupPolls) << "database error";
|
||||
job->_item->_status = SyncFileItem::FatalError;
|
||||
job->_item->_errorString = tr("Error writing metadata to the database");
|
||||
emit aborted(job->_item->_errorString);
|
||||
emit aborted(job->_item->_errorString, ErrorCategory::GenericError);
|
||||
deleteLater();
|
||||
return;
|
||||
}
|
||||
|
@ -1554,7 +1604,7 @@ QString OwncloudPropagator::remotePath() const
|
|||
|
||||
void PropagateIgnoreJob::start()
|
||||
{
|
||||
SyncFileItem::Status status = _item->_status;
|
||||
auto status = _item->_status;
|
||||
if (status == SyncFileItem::NoStatus) {
|
||||
if (_item->_instruction == CSYNC_INSTRUCTION_ERROR) {
|
||||
status = SyncFileItem::NormalError;
|
||||
|
@ -1568,7 +1618,7 @@ void PropagateIgnoreJob::start()
|
|||
_item->_file = conflictRecord.initialBasePath;
|
||||
}
|
||||
}
|
||||
done(status, _item->_errorString);
|
||||
done(status, _item->_errorString, ErrorCategory::NoError);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <QPointer>
|
||||
#include <QIODevice>
|
||||
#include <QMutex>
|
||||
#include <QNetworkReply>
|
||||
|
||||
#include "csync.h"
|
||||
#include "syncfileitem.h"
|
||||
|
@ -30,6 +31,7 @@
|
|||
#include "bandwidthmanager.h"
|
||||
#include "accountfwd.h"
|
||||
#include "syncoptions.h"
|
||||
#include "progressdispatcher.h"
|
||||
|
||||
#include <deque>
|
||||
|
||||
|
@ -147,6 +149,8 @@ signals:
|
|||
protected:
|
||||
[[nodiscard]] OwncloudPropagator *propagator() const;
|
||||
|
||||
static ErrorCategory errorCategoryFromNetworkError(const QNetworkReply::NetworkError error);
|
||||
|
||||
/** If this job gets added to a composite job, this will point to the parent.
|
||||
*
|
||||
* For the PropagateDirectory::_firstJob it will point to
|
||||
|
@ -165,7 +169,7 @@ class PropagateItemJob : public PropagatorJob
|
|||
{
|
||||
Q_OBJECT
|
||||
protected:
|
||||
virtual void done(SyncFileItem::Status status, const QString &errorString = QString());
|
||||
virtual void done(const SyncFileItem::Status status, const QString &errorString, const ErrorCategory category);
|
||||
|
||||
/*
|
||||
* set a custom restore job message that is used if the restore job succeeded.
|
||||
|
@ -640,7 +644,7 @@ private slots:
|
|||
|
||||
signals:
|
||||
void newItem(const OCC::SyncFileItemPtr &);
|
||||
void itemCompleted(const OCC::SyncFileItemPtr &);
|
||||
void itemCompleted(const SyncFileItemPtr &item, OCC::ErrorCategory category);
|
||||
void progress(const OCC::SyncFileItem &, qint64 bytes);
|
||||
void finished(bool success);
|
||||
|
||||
|
@ -721,7 +725,7 @@ public:
|
|||
void start();
|
||||
signals:
|
||||
void finished();
|
||||
void aborted(const QString &error);
|
||||
void aborted(const QString &error, const ErrorCategory errorCategory);
|
||||
private slots:
|
||||
void slotPollFinished();
|
||||
};
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
namespace OCC {
|
||||
|
||||
OCSYNC_EXPORT Q_NAMESPACE
|
||||
|
||||
/**
|
||||
* @brief The ProgressInfo class
|
||||
* @ingroup libsync
|
||||
|
@ -249,9 +251,12 @@ namespace Progress {
|
|||
* in IssuesWidget.
|
||||
*/
|
||||
enum class ErrorCategory {
|
||||
Normal,
|
||||
NoError,
|
||||
GenericError,
|
||||
NetworkError,
|
||||
InsufficientRemoteStorage,
|
||||
};
|
||||
Q_ENUM_NS(OCC::ErrorCategory)
|
||||
|
||||
/**
|
||||
* @file progressdispatcher.h
|
||||
|
@ -283,7 +288,7 @@ signals:
|
|||
/**
|
||||
* @brief: the item was completed by a job
|
||||
*/
|
||||
void itemCompleted(const QString &folder, const OCC::SyncFileItemPtr &item);
|
||||
void itemCompleted(const QString &folder, const OCC::SyncFileItemPtr &item, const OCC::ErrorCategory category);
|
||||
|
||||
/**
|
||||
* @brief A new folder-wide sync error was seen.
|
||||
|
@ -297,7 +302,7 @@ signals:
|
|||
* @param[out] full error message
|
||||
* @param[out] subject (optional)
|
||||
*/
|
||||
void addErrorToGui(const QString &folder, OCC::SyncFileItem::Status status, const QString &errorMessage, const QString &subject);
|
||||
void addErrorToGui(const QString &folder, const OCC::SyncFileItem::Status status, const QString &errorMessage, const QString &subject, const OCC::ErrorCategory category);
|
||||
|
||||
/**
|
||||
* @brief Emitted for a folder when a sync is done, listing all pending conflicts
|
||||
|
|
|
@ -461,7 +461,7 @@ void PropagateDownloadFile::start()
|
|||
SyncJournalFileRecord parentRec;
|
||||
if (!propagator()->_journal->getFileRecord(parentPath, &parentRec)) {
|
||||
qCWarning(lcPropagateDownload) << "could not get file from local DB" << parentPath;
|
||||
done(SyncFileItem::NormalError, tr("could not get file %1 from local DB").arg(parentPath));
|
||||
done(SyncFileItem::NormalError, tr("could not get file %1 from local DB").arg(parentPath), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -478,7 +478,7 @@ void PropagateDownloadFile::start()
|
|||
});
|
||||
connect(_downloadEncryptedHelper, &PropagateDownloadEncrypted::failed, [this] {
|
||||
done(SyncFileItem::NormalError,
|
||||
tr("File %1 cannot be downloaded because encryption information is missing.").arg(QDir::toNativeSeparators(_item->_file)));
|
||||
tr("File %1 cannot be downloaded because encryption information is missing.").arg(QDir::toNativeSeparators(_item->_file)), ErrorCategory::GenericError);
|
||||
});
|
||||
_downloadEncryptedHelper->start();
|
||||
}
|
||||
|
@ -496,20 +496,20 @@ void PropagateDownloadFile::startAfterIsEncryptedIsChecked()
|
|||
QString fsPath = propagator()->fullLocalPath(_item->_file);
|
||||
if (!FileSystem::verifyFileUnchanged(fsPath, _item->_previousSize, _item->_previousModtime)) {
|
||||
propagator()->_anotherSyncNeeded = true;
|
||||
done(SyncFileItem::SoftError, tr("File has changed since discovery"));
|
||||
done(SyncFileItem::SoftError, tr("File has changed since discovery"), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(lcPropagateDownload) << "dehydrating file" << _item->_file;
|
||||
auto r = vfs->dehydratePlaceholder(*_item);
|
||||
if (!r) {
|
||||
done(SyncFileItem::NormalError, r.error());
|
||||
done(SyncFileItem::NormalError, r.error(), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!propagator()->_journal->deleteFileRecord(_item->_originalFile)) {
|
||||
qCWarning(lcPropagateDownload) << "could not delete file from local DB" << _item->_originalFile;
|
||||
done(SyncFileItem::NormalError, tr("Could not delete file record %1 from local DB").arg(_item->_originalFile));
|
||||
done(SyncFileItem::NormalError, tr("Could not delete file record %1 from local DB").arg(_item->_originalFile), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -530,12 +530,12 @@ void PropagateDownloadFile::startAfterIsEncryptedIsChecked()
|
|||
qCDebug(lcPropagateDownload) << "creating virtual file" << _item->_file;
|
||||
// do a klaas' case clash check.
|
||||
if (propagator()->localFileNameClash(_item->_file)) {
|
||||
done(SyncFileItem::FileNameClash, tr("File %1 can not be downloaded because of a local file name clash!").arg(QDir::toNativeSeparators(_item->_file)));
|
||||
done(SyncFileItem::FileNameClash, tr("File %1 can not be downloaded because of a local file name clash!").arg(QDir::toNativeSeparators(_item->_file)), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
auto r = vfs->createPlaceholder(*_item);
|
||||
if (!r) {
|
||||
done(SyncFileItem::NormalError, r.error());
|
||||
done(SyncFileItem::NormalError, r.error(), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
updateMetadata(false);
|
||||
|
@ -675,7 +675,7 @@ void PropagateDownloadFile::startDownload()
|
|||
FileSystem::setFileReadOnly(_tmpFile.fileName(), false);
|
||||
if (!_tmpFile.open(QIODevice::Append | QIODevice::Unbuffered)) {
|
||||
qCWarning(lcPropagateDownload) << "could not open temporary file" << _tmpFile.fileName();
|
||||
done(SyncFileItem::NormalError, _tmpFile.errorString());
|
||||
done(SyncFileItem::NormalError, _tmpFile.errorString(), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
// Hide temporary after creation
|
||||
|
@ -689,11 +689,11 @@ void PropagateDownloadFile::startDownload()
|
|||
// tab: instead we'll generate a general "disk space low" message and show
|
||||
// these detail errors only in the error view.
|
||||
done(SyncFileItem::DetailError,
|
||||
tr("The download would reduce free local disk space below the limit"));
|
||||
tr("The download would reduce free local disk space below the limit"), ErrorCategory::GenericError);
|
||||
emit propagator()->insufficientLocalStorage();
|
||||
} else if (diskSpaceResult == OwncloudPropagator::DiskSpaceCritical) {
|
||||
done(SyncFileItem::FatalError,
|
||||
tr("Free space on disk is less than %1").arg(Utility::octetsToString(criticalFreeSpaceLimit())));
|
||||
tr("Free space on disk is less than %1").arg(Utility::octetsToString(criticalFreeSpaceLimit())), ErrorCategory::GenericError);
|
||||
}
|
||||
|
||||
// Remove the temporary, if empty.
|
||||
|
@ -832,7 +832,7 @@ void PropagateDownloadFile::slotGetFinished()
|
|||
&propagator()->_anotherSyncNeeded, errorBody);
|
||||
}
|
||||
|
||||
done(status, errorString);
|
||||
done(status, errorString, errorCategoryFromNetworkError(err));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -880,14 +880,14 @@ void PropagateDownloadFile::slotGetFinished()
|
|||
// This happened when trying to resume a file. The Content-Range header was files, Content-Length was == 0
|
||||
qCDebug(lcPropagateDownload) << bodySize << _item->_size << _tmpFile.size() << job->resumeStart();
|
||||
FileSystem::remove(_tmpFile.fileName());
|
||||
done(SyncFileItem::SoftError, QLatin1String("Broken webserver returning empty content length for non-empty file on resume"));
|
||||
done(SyncFileItem::SoftError, QLatin1String("Broken webserver returning empty content length for non-empty file on resume"), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bodySize > 0 && bodySize != _tmpFile.size() - job->resumeStart()) {
|
||||
qCDebug(lcPropagateDownload) << bodySize << _tmpFile.size() << job->resumeStart();
|
||||
propagator()->_anotherSyncNeeded = true;
|
||||
done(SyncFileItem::SoftError, tr("The file could not be downloaded completely."));
|
||||
done(SyncFileItem::SoftError, tr("The file could not be downloaded completely."), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -895,7 +895,7 @@ void PropagateDownloadFile::slotGetFinished()
|
|||
FileSystem::remove(_tmpFile.fileName());
|
||||
done(SyncFileItem::NormalError,
|
||||
tr("The downloaded file is empty, but the server said it should have been %1.")
|
||||
.arg(Utility::octetsToString(_item->_size)));
|
||||
.arg(Utility::octetsToString(_item->_size)), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -984,7 +984,7 @@ void PropagateDownloadFile::checksumValidateFailedAbortDownload(const QString &e
|
|||
{
|
||||
FileSystem::remove(_tmpFile.fileName());
|
||||
propagator()->_anotherSyncNeeded = true;
|
||||
done(SyncFileItem::SoftError, errMsg); // tr("The file downloaded with a broken checksum, will be redownloaded."));
|
||||
done(SyncFileItem::SoftError, errMsg, ErrorCategory::GenericError); // tr("The file downloaded with a broken checksum, will be redownloaded."));
|
||||
}
|
||||
|
||||
void PropagateDownloadFile::deleteExistingFolder()
|
||||
|
@ -1005,7 +1005,7 @@ void PropagateDownloadFile::deleteExistingFolder()
|
|||
|
||||
QString error;
|
||||
if (!propagator()->createConflict(_item, _associatedComposite, &error)) {
|
||||
done(SyncFileItem::NormalError, error);
|
||||
done(SyncFileItem::NormalError, error, ErrorCategory::GenericError);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1141,7 +1141,7 @@ void PropagateDownloadFile::finalizeDownload()
|
|||
if (_downloadEncryptedHelper->decryptFile(_tmpFile)) {
|
||||
downloadFinished();
|
||||
} else {
|
||||
done(SyncFileItem::NormalError, _downloadEncryptedHelper->errorString());
|
||||
done(SyncFileItem::NormalError, _downloadEncryptedHelper->errorString(), ErrorCategory::GenericError);
|
||||
}
|
||||
} else {
|
||||
downloadFinished();
|
||||
|
@ -1155,7 +1155,7 @@ void PropagateDownloadFile::downloadFinished()
|
|||
|
||||
if (_item->_modtime <= 0) {
|
||||
FileSystem::remove(_tmpFile.fileName());
|
||||
done(SyncFileItem::NormalError, tr("File %1 has invalid modified time reported by server. Do not save it.").arg(QDir::toNativeSeparators(_item->_file)));
|
||||
done(SyncFileItem::NormalError, tr("File %1 has invalid modified time reported by server. Do not save it.").arg(QDir::toNativeSeparators(_item->_file)), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
Q_ASSERT(_item->_modtime > 0);
|
||||
|
@ -1168,7 +1168,7 @@ void PropagateDownloadFile::downloadFinished()
|
|||
_item->_modtime = FileSystem::getModTime(_tmpFile.fileName());
|
||||
if (_item->_modtime <= 0) {
|
||||
FileSystem::remove(_tmpFile.fileName());
|
||||
done(SyncFileItem::NormalError, tr("File %1 has invalid modified time reported by server. Do not save it.").arg(QDir::toNativeSeparators(_item->_file)));
|
||||
done(SyncFileItem::NormalError, tr("File %1 has invalid modified time reported by server. Do not save it.").arg(QDir::toNativeSeparators(_item->_file)), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
Q_ASSERT(_item->_modtime > 0);
|
||||
|
@ -1193,7 +1193,7 @@ void PropagateDownloadFile::downloadFinished()
|
|||
// Make the file a hydrated placeholder if possible
|
||||
const auto result = propagator()->syncOptions()._vfs->convertToPlaceholder(_tmpFile.fileName(), *_item, filename);
|
||||
if (!result) {
|
||||
done(SyncFileItem::NormalError, result.error());
|
||||
done(SyncFileItem::NormalError, result.error(), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1210,15 +1210,15 @@ void PropagateDownloadFile::downloadFinished()
|
|||
qCInfo(lcPropagateDownload) << "downloading case clashed file" << _item->_file;
|
||||
const auto caseClashConflictResult = propagator()->createCaseClashConflict(_item, _tmpFile.fileName());
|
||||
if (caseClashConflictResult) {
|
||||
done(SyncFileItem::SoftError, *caseClashConflictResult);
|
||||
done(SyncFileItem::SoftError, *caseClashConflictResult, ErrorCategory::GenericError);
|
||||
} else {
|
||||
done(SyncFileItem::FileNameClash, tr("File %1 downloaded but it resulted in a local file name clash!").arg(QDir::toNativeSeparators(_item->_file)));
|
||||
done(SyncFileItem::FileNameClash, tr("File %1 downloaded but it resulted in a local file name clash!").arg(QDir::toNativeSeparators(_item->_file)), ErrorCategory::GenericError);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
QString error;
|
||||
if (!propagator()->createConflict(_item, _associatedComposite, &error)) {
|
||||
done(SyncFileItem::SoftError, error);
|
||||
done(SyncFileItem::SoftError, error, ErrorCategory::GenericError);
|
||||
} else {
|
||||
previousFileExists = false;
|
||||
}
|
||||
|
@ -1240,7 +1240,7 @@ void PropagateDownloadFile::downloadFinished()
|
|||
const time_t expectedMtime = _item->_previousModtime;
|
||||
if (!FileSystem::verifyFileUnchanged(filename, expectedSize, expectedMtime)) {
|
||||
propagator()->_anotherSyncNeeded = true;
|
||||
done(SyncFileItem::SoftError, tr("File has changed since discovery"));
|
||||
done(SyncFileItem::SoftError, tr("File has changed since discovery"), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1258,7 +1258,7 @@ void PropagateDownloadFile::downloadFinished()
|
|||
propagator()->_anotherSyncNeeded = true;
|
||||
}
|
||||
|
||||
done(SyncFileItem::SoftError, error);
|
||||
done(SyncFileItem::SoftError, error, ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1290,7 +1290,7 @@ void PropagateDownloadFile::downloadFinished()
|
|||
|
||||
if (!propagator()->_journal->deleteFileRecord(virtualFile)) {
|
||||
qCWarning(lcPropagateDownload) << "could not delete file from local DB" << virtualFile;
|
||||
done(SyncFileItem::NormalError, tr("Could not delete file record %1 from local DB").arg(virtualFile));
|
||||
done(SyncFileItem::NormalError, tr("Could not delete file record %1 from local DB").arg(virtualFile), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1322,10 +1322,10 @@ void PropagateDownloadFile::updateMetadata(bool isConflict)
|
|||
const QString fn = propagator()->fullLocalPath(_item->_file);
|
||||
const auto result = propagator()->updateMetadata(*_item);
|
||||
if (!result) {
|
||||
done(SyncFileItem::FatalError, tr("Error updating metadata: %1").arg(result.error()));
|
||||
done(SyncFileItem::FatalError, tr("Error updating metadata: %1").arg(result.error()), ErrorCategory::GenericError);
|
||||
return;
|
||||
} else if (*result == Vfs::ConvertToPlaceholderResult::Locked) {
|
||||
done(SyncFileItem::SoftError, tr("The file %1 is currently in use").arg(_item->_file));
|
||||
done(SyncFileItem::SoftError, tr("The file %1 is currently in use").arg(_item->_file), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1337,7 +1337,7 @@ void PropagateDownloadFile::updateMetadata(bool isConflict)
|
|||
|
||||
propagator()->_journal->commit("download file start2");
|
||||
|
||||
done(isConflict ? SyncFileItem::Conflict : SyncFileItem::Success);
|
||||
done(isConflict ? SyncFileItem::Conflict : SyncFileItem::Success, {}, ErrorCategory::NoError);
|
||||
|
||||
// handle the special recall file
|
||||
if (!_item->_remotePerm.hasPermission(RemotePermissions::IsShared)
|
||||
|
|
|
@ -45,9 +45,9 @@ void PropagateRemoteDelete::start()
|
|||
if (_deleteEncryptedHelper->networkError() != QNetworkReply::NoError && _deleteEncryptedHelper->networkError() != QNetworkReply::ContentNotFoundError) {
|
||||
status = classifyError(_deleteEncryptedHelper->networkError(), _item->_httpErrorCode, &propagator()->_anotherSyncNeeded);
|
||||
}
|
||||
done(status, _deleteEncryptedHelper->errorString());
|
||||
done(status, _deleteEncryptedHelper->errorString(), ErrorCategory::GenericError);
|
||||
} else {
|
||||
done(SyncFileItem::Success);
|
||||
done(SyncFileItem::Success, {}, ErrorCategory::NoError);
|
||||
}
|
||||
});
|
||||
_deleteEncryptedHelper->start();
|
||||
|
@ -94,7 +94,8 @@ void PropagateRemoteDelete::slotDeleteJobFinished()
|
|||
if (err != QNetworkReply::NoError && err != QNetworkReply::ContentNotFoundError) {
|
||||
SyncFileItem::Status status = classifyError(err, _item->_httpErrorCode,
|
||||
&propagator()->_anotherSyncNeeded);
|
||||
done(status, _job->errorString());
|
||||
|
||||
done(status, _job->errorString(), errorCategoryFromNetworkError(err));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -109,18 +110,18 @@ void PropagateRemoteDelete::slotDeleteJobFinished()
|
|||
done(SyncFileItem::NormalError,
|
||||
tr("Wrong HTTP code returned by server. Expected 204, but received \"%1 %2\".")
|
||||
.arg(_item->_httpErrorCode)
|
||||
.arg(_job->reply()->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString()));
|
||||
.arg(_job->reply()->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString()), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!propagator()->_journal->deleteFileRecord(_item->_originalFile, _item->isDirectory())) {
|
||||
qCWarning(lcPropagateRemoteDelete) << "could not delete file from local DB" << _item->_originalFile;
|
||||
done(SyncFileItem::NormalError, tr("Could not delete file record %1 from local DB").arg(_item->_originalFile));
|
||||
done(SyncFileItem::NormalError, tr("Could not delete file record %1 from local DB").arg(_item->_originalFile), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
propagator()->_journal->commit("Remote Remove");
|
||||
|
||||
done(SyncFileItem::Success);
|
||||
done(SyncFileItem::Success, {}, ErrorCategory::NoError);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,7 +123,7 @@ void PropagateRemoteMkdir::finalizeMkColJob(QNetworkReply::NetworkError err, con
|
|||
} else if (err != QNetworkReply::NoError) {
|
||||
SyncFileItem::Status status = classifyError(err, _item->_httpErrorCode,
|
||||
&propagator()->_anotherSyncNeeded);
|
||||
done(status, _item->_errorString);
|
||||
done(status, _item->_errorString, errorCategoryFromNetworkError(err));
|
||||
return;
|
||||
} else if (_item->_httpErrorCode != 201) {
|
||||
// Normally we expect "201 Created"
|
||||
|
@ -132,7 +132,7 @@ void PropagateRemoteMkdir::finalizeMkColJob(QNetworkReply::NetworkError err, con
|
|||
done(SyncFileItem::NormalError,
|
||||
tr("Wrong HTTP code returned by server. Expected 201, but received \"%1 %2\".")
|
||||
.arg(_item->_httpErrorCode)
|
||||
.arg(jobHttpReasonPhraseString));
|
||||
.arg(jobHttpReasonPhraseString), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -161,10 +161,10 @@ void PropagateRemoteMkdir::finalizeMkColJob(QNetworkReply::NetworkError err, con
|
|||
job->start();
|
||||
}
|
||||
});
|
||||
connect(propfindJob, &PropfindJob::finishedWithError, this, [this]{
|
||||
// ignore the PROPFIND error
|
||||
connect(propfindJob, &PropfindJob::finishedWithError, this, [this] (QNetworkReply *reply) {
|
||||
const auto err = reply ? reply->error() : QNetworkReply::NetworkError::UnknownNetworkError;
|
||||
propagator()->_activeJobList.removeOne(this);
|
||||
done(SyncFileItem::NormalError);
|
||||
done(SyncFileItem::NormalError, {}, errorCategoryFromNetworkError(err));
|
||||
});
|
||||
propfindJob->start();
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ void PropagateRemoteMkdir::slotMkdir()
|
|||
const auto targetFile = propagator()->fullLocalPath(_item->_renameTarget);
|
||||
QString renameError;
|
||||
if (!FileSystem::rename(existingFile, targetFile, &renameError)) {
|
||||
done(SyncFileItem::NormalError, renameError);
|
||||
done(SyncFileItem::NormalError, renameError, ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
emit propagator()->touchedFile(existingFile);
|
||||
|
@ -190,7 +190,7 @@ void PropagateRemoteMkdir::slotMkdir()
|
|||
SyncJournalFileRecord parentRec;
|
||||
bool ok = propagator()->_journal->getFileRecord(parentPath, &parentRec);
|
||||
if (!ok) {
|
||||
done(SyncFileItem::NormalError);
|
||||
done(SyncFileItem::NormalError, {}, ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -257,13 +257,13 @@ void PropagateRemoteMkdir::success()
|
|||
// save the file id already so we can detect rename or remove
|
||||
const auto result = propagator()->updateMetadata(itemCopy);
|
||||
if (!result) {
|
||||
done(SyncFileItem::FatalError, tr("Error writing metadata to the database: %1").arg(result.error()));
|
||||
done(SyncFileItem::FatalError, tr("Error writing metadata to the database: %1").arg(result.error()), ErrorCategory::GenericError);
|
||||
return;
|
||||
} else if (*result == Vfs::ConvertToPlaceholderResult::Locked) {
|
||||
done(SyncFileItem::FatalError, tr("The file %1 is currently in use").arg(_item->_file));
|
||||
done(SyncFileItem::FatalError, tr("The file %1 is currently in use").arg(_item->_file), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
done(SyncFileItem::Success);
|
||||
done(SyncFileItem::Success, {}, ErrorCategory::NoError);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ void PropagateRemoteMove::start()
|
|||
SyncJournalFileRecord parentRec;
|
||||
bool ok = propagator()->_journal->getFileRecord(parentPath, &parentRec);
|
||||
if (!ok) {
|
||||
done(SyncFileItem::NormalError);
|
||||
done(SyncFileItem::NormalError, {}, ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -167,7 +167,7 @@ void PropagateRemoteMove::start()
|
|||
QString error;
|
||||
if (!FileSystem::uncheckedRenameReplace(localTargetAlt, localTarget, &error)) {
|
||||
done(SyncFileItem::NormalError, tr("Could not rename %1 to %2, error: %3")
|
||||
.arg(folderTargetAlt, folderTarget, error));
|
||||
.arg(folderTargetAlt, folderTarget, error), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
qCInfo(lcPropagateRemoteMove) << "Suffix vfs required local rename of"
|
||||
|
@ -217,7 +217,7 @@ void PropagateRemoteMove::slotMoveJobFinished()
|
|||
<< "Could not MOVE file" << filePathOriginal << " to" << filePath
|
||||
<< " with error:" << _job->errorString() << " and successfully restored it.";
|
||||
}
|
||||
done(status, _job->errorString());
|
||||
done(status, _job->errorString(), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -228,7 +228,7 @@ void PropagateRemoteMove::slotMoveJobFinished()
|
|||
done(SyncFileItem::NormalError,
|
||||
tr("Wrong HTTP code returned by server. Expected 201, but received \"%1 %2\".")
|
||||
.arg(_item->_httpErrorCode)
|
||||
.arg(_job->reply()->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString()));
|
||||
.arg(_job->reply()->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString()), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -245,7 +245,7 @@ void PropagateRemoteMove::finalize()
|
|||
SyncJournalFileRecord oldRecord;
|
||||
if (!propagator()->_journal->getFileRecord(_item->_originalFile, &oldRecord)) {
|
||||
qCWarning(lcPropagateRemoteMove) << "could not get file from local DB" << _item->_originalFile;
|
||||
done(SyncFileItem::NormalError, tr("could not get file %1 from local DB").arg(_item->_originalFile));
|
||||
done(SyncFileItem::NormalError, tr("could not get file %1 from local DB").arg(_item->_originalFile), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
auto &vfs = propagator()->syncOptions()._vfs;
|
||||
|
@ -257,7 +257,7 @@ void PropagateRemoteMove::finalize()
|
|||
// Delete old db data.
|
||||
if (!propagator()->_journal->deleteFileRecord(_item->_originalFile)) {
|
||||
qCWarning(lcPropagateRemoteMove) << "could not delete file from local DB" << _item->_originalFile;
|
||||
done(SyncFileItem::NormalError, tr("Could not delete file record %1 from local DB").arg(_item->_originalFile));
|
||||
done(SyncFileItem::NormalError, tr("Could not delete file record %1 from local DB").arg(_item->_originalFile), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
if (!vfs->setPinState(_item->_originalFile, PinState::Inherited)) {
|
||||
|
@ -279,34 +279,34 @@ void PropagateRemoteMove::finalize()
|
|||
|
||||
if (!QFileInfo::exists(targetFile)) {
|
||||
propagator()->_journal->commit("Remote Rename");
|
||||
done(SyncFileItem::Success);
|
||||
done(SyncFileItem::Success, {}, ErrorCategory::NoError);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto result = propagator()->updateMetadata(newItem);
|
||||
if (!result) {
|
||||
done(SyncFileItem::FatalError, tr("Error updating metadata: %1").arg(result.error()));
|
||||
done(SyncFileItem::FatalError, tr("Error updating metadata: %1").arg(result.error()), ErrorCategory::GenericError);
|
||||
return;
|
||||
} else if (*result == Vfs::ConvertToPlaceholderResult::Locked) {
|
||||
done(SyncFileItem::SoftError, tr("The file %1 is currently in use").arg(newItem._file));
|
||||
done(SyncFileItem::SoftError, tr("The file %1 is currently in use").arg(newItem._file), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
if (pinState && *pinState != PinState::Inherited
|
||||
&& !vfs->setPinState(newItem._renameTarget, *pinState)) {
|
||||
done(SyncFileItem::NormalError, tr("Error setting pin state"));
|
||||
done(SyncFileItem::NormalError, tr("Error setting pin state"), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_item->isDirectory()) {
|
||||
propagator()->_renamedDirectories.insert(_item->_file, _item->_renameTarget);
|
||||
if (!adjustSelectiveSync(propagator()->_journal, _item->_file, _item->_renameTarget)) {
|
||||
done(SyncFileItem::FatalError, tr("Error writing metadata to the database"));
|
||||
done(SyncFileItem::FatalError, tr("Error writing metadata to the database"), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
propagator()->_journal->commit("Remote Rename");
|
||||
done(SyncFileItem::Success);
|
||||
done(SyncFileItem::Success, {}, ErrorCategory::NoError);
|
||||
}
|
||||
|
||||
bool PropagateRemoteMove::adjustSelectiveSync(SyncJournalDb *journal, const QString &from_, const QString &to_)
|
||||
|
|
|
@ -629,10 +629,10 @@ void PropagateUploadFileCommon::slotPollFinished()
|
|||
finalize();
|
||||
}
|
||||
|
||||
void PropagateUploadFileCommon::done(SyncFileItem::Status status, const QString &errorString)
|
||||
void PropagateUploadFileCommon::done(SyncFileItem::Status status, const QString &errorString, const ErrorCategory category)
|
||||
{
|
||||
_finished = true;
|
||||
PropagateItemJob::done(status, errorString);
|
||||
PropagateItemJob::done(status, errorString, category);
|
||||
}
|
||||
|
||||
void PropagateUploadFileCommon::checkResettingErrors()
|
||||
|
|
|
@ -281,7 +281,7 @@ private slots:
|
|||
void slotPollFinished();
|
||||
|
||||
protected:
|
||||
void done(SyncFileItem::Status status, const QString &errorString = QString()) override;
|
||||
void done(SyncFileItem::Status status, const QString &errorString = QString(), const ErrorCategory category = ErrorCategory::NoError) override;
|
||||
|
||||
/**
|
||||
* Aborts all running network jobs, except for the ones that mayAbortJob
|
||||
|
|
|
@ -102,7 +102,7 @@ void PropagateLocalRemove::start()
|
|||
qCInfo(lcPropagateLocalRemove) << "Going to delete:" << filename;
|
||||
|
||||
if (propagator()->localFileNameClash(_item->_file)) {
|
||||
done(SyncFileItem::FileNameClash, tr("Could not remove %1 because of a local file name clash").arg(QDir::toNativeSeparators(filename)));
|
||||
done(SyncFileItem::FileNameClash, tr("Could not remove %1 because of a local file name clash").arg(QDir::toNativeSeparators(filename)), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -110,19 +110,19 @@ void PropagateLocalRemove::start()
|
|||
if (_moveToTrash) {
|
||||
if ((QDir(filename).exists() || FileSystem::fileExists(filename))
|
||||
&& !FileSystem::moveToTrash(filename, &removeError)) {
|
||||
done(SyncFileItem::NormalError, removeError);
|
||||
done(SyncFileItem::NormalError, removeError, ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (_item->isDirectory()) {
|
||||
if (QDir(filename).exists() && !removeRecursively(QString())) {
|
||||
done(SyncFileItem::NormalError, _error);
|
||||
done(SyncFileItem::NormalError, _error, ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (FileSystem::fileExists(filename)
|
||||
&& !FileSystem::remove(filename, &removeError)) {
|
||||
done(SyncFileItem::NormalError, removeError);
|
||||
done(SyncFileItem::NormalError, removeError, ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -130,11 +130,11 @@ void PropagateLocalRemove::start()
|
|||
propagator()->reportProgress(*_item, 0);
|
||||
if (!propagator()->_journal->deleteFileRecord(_item->_originalFile, _item->isDirectory())) {
|
||||
qCWarning(lcPropagateLocalRename) << "could not delete file from local DB" << _item->_originalFile;
|
||||
done(SyncFileItem::NormalError, tr("Could not delete file record %1 from local DB").arg(_item->_originalFile));
|
||||
done(SyncFileItem::NormalError, tr("Could not delete file record %1 from local DB").arg(_item->_originalFile), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
propagator()->_journal->commit("Local remove");
|
||||
done(SyncFileItem::Success);
|
||||
done(SyncFileItem::Success, {}, ErrorCategory::NoError);
|
||||
}
|
||||
|
||||
void PropagateLocalMkdir::start()
|
||||
|
@ -164,13 +164,13 @@ void PropagateLocalMkdir::startLocalMkdir()
|
|||
if (!FileSystem::remove(newDirStr, &removeError)) {
|
||||
done(SyncFileItem::NormalError,
|
||||
tr("could not delete file %1, error: %2")
|
||||
.arg(newDirStr, removeError));
|
||||
.arg(newDirStr, removeError), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
} else if (_item->_instruction == CSYNC_INSTRUCTION_CONFLICT) {
|
||||
QString error;
|
||||
if (!propagator()->createConflict(_item, _associatedComposite, &error)) {
|
||||
done(SyncFileItem::SoftError, error);
|
||||
done(SyncFileItem::SoftError, error, ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -178,13 +178,13 @@ void PropagateLocalMkdir::startLocalMkdir()
|
|||
|
||||
if (Utility::fsCasePreserving() && propagator()->localFileNameClash(_item->_file)) {
|
||||
qCWarning(lcPropagateLocalMkdir) << "New folder to create locally already exists with different case:" << _item->_file;
|
||||
done(SyncFileItem::FileNameClash, tr("Folder %1 cannot be created because of a local file or folder name clash!").arg(newDirStr));
|
||||
done(SyncFileItem::FileNameClash, tr("Folder %1 cannot be created because of a local file or folder name clash!").arg(newDirStr), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
emit propagator()->touchedFile(newDirStr);
|
||||
QDir localDir(propagator()->localPath());
|
||||
if (!localDir.mkpath(_item->_file)) {
|
||||
done(SyncFileItem::NormalError, tr("Could not create folder %1").arg(newDirStr));
|
||||
done(SyncFileItem::NormalError, tr("Could not create folder %1").arg(newDirStr), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -197,10 +197,10 @@ void PropagateLocalMkdir::startLocalMkdir()
|
|||
newItem._etag = "_invalid_";
|
||||
const auto result = propagator()->updateMetadata(newItem);
|
||||
if (!result) {
|
||||
done(SyncFileItem::FatalError, tr("Error updating metadata: %1").arg(result.error()));
|
||||
done(SyncFileItem::FatalError, tr("Error updating metadata: %1").arg(result.error()), ErrorCategory::GenericError);
|
||||
return;
|
||||
} else if (*result == Vfs::ConvertToPlaceholderResult::Locked) {
|
||||
done(SyncFileItem::SoftError, tr("The file %1 is currently in use").arg(newItem._file));
|
||||
done(SyncFileItem::SoftError, tr("The file %1 is currently in use").arg(newItem._file), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
propagator()->_journal->commit("localMkdir");
|
||||
|
@ -208,7 +208,7 @@ void PropagateLocalMkdir::startLocalMkdir()
|
|||
auto resultStatus = _item->_instruction == CSYNC_INSTRUCTION_CONFLICT
|
||||
? SyncFileItem::Conflict
|
||||
: SyncFileItem::Success;
|
||||
done(resultStatus);
|
||||
done(resultStatus, {}, ErrorCategory::NoError);
|
||||
}
|
||||
|
||||
PropagateLocalRename::PropagateLocalRename(OwncloudPropagator *propagator, const SyncFileItemPtr &item)
|
||||
|
@ -249,9 +249,9 @@ void PropagateLocalRename::start()
|
|||
qCInfo(lcPropagateLocalRename) << "renaming a case clashed file" << _item->_file << _item->_renameTarget;
|
||||
const auto caseClashConflictResult = propagator()->createCaseClashConflict(_item, existingFile);
|
||||
if (caseClashConflictResult) {
|
||||
done(SyncFileItem::SoftError, *caseClashConflictResult);
|
||||
done(SyncFileItem::SoftError, *caseClashConflictResult, ErrorCategory::GenericError);
|
||||
} else {
|
||||
done(SyncFileItem::FileNameClash, tr("File %1 downloaded but it resulted in a local file name clash!").arg(QDir::toNativeSeparators(_item->_file)));
|
||||
done(SyncFileItem::FileNameClash, tr("File %1 downloaded but it resulted in a local file name clash!").arg(QDir::toNativeSeparators(_item->_file)), ErrorCategory::GenericError);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -259,7 +259,7 @@ void PropagateLocalRename::start()
|
|||
emit propagator()->touchedFile(existingFile);
|
||||
emit propagator()->touchedFile(targetFile);
|
||||
if (QString renameError; !FileSystem::rename(existingFile, targetFile, &renameError)) {
|
||||
done(SyncFileItem::NormalError, renameError);
|
||||
done(SyncFileItem::NormalError, renameError, ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -267,19 +267,20 @@ void PropagateLocalRename::start()
|
|||
SyncJournalFileRecord oldRecord;
|
||||
if (!propagator()->_journal->getFileRecord(fileAlreadyMoved ? previousNameInDb : _item->_originalFile, &oldRecord)) {
|
||||
qCWarning(lcPropagateLocalRename) << "could not get file from local DB" << _item->_originalFile;
|
||||
done(SyncFileItem::NormalError, tr("could not get file %1 from local DB").arg(_item->_originalFile));
|
||||
done(SyncFileItem::NormalError, tr("could not get file %1 from local DB").arg(_item->_originalFile), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fileAlreadyMoved && !deleteOldDbRecord(previousNameInDb)) {
|
||||
return;
|
||||
} else if (!deleteOldDbRecord(_item->_originalFile)) {
|
||||
qCWarning(lcPropagateLocalRename) << "could not delete file from local DB" << _item->_originalFile;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!vfs->setPinState(_item->_renameTarget, pinState)) {
|
||||
qCWarning(lcPropagateLocalRename) << "Could not set pin state of" << _item->_renameTarget << "to old value" << pinState;
|
||||
done(SyncFileItem::NormalError, tr("Error setting pin state"));
|
||||
done(SyncFileItem::NormalError, tr("Error setting pin state"), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -292,10 +293,10 @@ void PropagateLocalRename::start()
|
|||
}
|
||||
const auto result = propagator()->updateMetadata(newItem);
|
||||
if (!result) {
|
||||
done(SyncFileItem::FatalError, tr("Error updating metadata: %1").arg(result.error()));
|
||||
done(SyncFileItem::FatalError, tr("Error updating metadata: %1").arg(result.error()), ErrorCategory::GenericError);
|
||||
return;
|
||||
} else if (*result == Vfs::ConvertToPlaceholderResult::Locked) {
|
||||
done(SyncFileItem::SoftError, tr("The file %1 is currently in use").arg(newItem._file));
|
||||
done(SyncFileItem::SoftError, tr("The file %1 is currently in use").arg(newItem._file), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
@ -312,12 +313,12 @@ void PropagateLocalRename::start()
|
|||
SyncJournalFileRecord oldRecord;
|
||||
if (!propagator()->_journal->getFileRecord(oldFileName, &oldRecord)) {
|
||||
qCWarning(lcPropagateLocalRename) << "could not get file from local DB" << oldFileName;
|
||||
done(SyncFileItem::NormalError, tr("could not get file %1 from local DB").arg(oldFileNameString));
|
||||
done(SyncFileItem::NormalError, tr("could not get file %1 from local DB").arg(oldFileNameString), OCC::ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
if (!propagator()->_journal->deleteFileRecord(oldFileName)) {
|
||||
qCWarning(lcPropagateLocalRename) << "could not delete file from local DB" << oldFileName;
|
||||
done(SyncFileItem::NormalError, tr("Could not delete file record %1 from local DB").arg(oldFileNameString));
|
||||
done(SyncFileItem::NormalError, tr("Could not delete file record %1 from local DB").arg(oldFileNameString), OCC::ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -325,36 +326,40 @@ void PropagateLocalRename::start()
|
|||
newItem->_file = newFileNameString;
|
||||
const auto result = propagator()->updateMetadata(*newItem);
|
||||
if (!result) {
|
||||
done(SyncFileItem::FatalError, tr("Error updating metadata: %1").arg(result.error()));
|
||||
done(SyncFileItem::FatalError, tr("Error updating metadata: %1").arg(result.error()), OCC::ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
});
|
||||
if (!dbQueryResult) {
|
||||
done(SyncFileItem::FatalError, tr("Failed to propagate directory rename in hierarchy"));
|
||||
done(SyncFileItem::FatalError, tr("Failed to propagate directory rename in hierarchy"), OCC::ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
propagator()->_renamedDirectories.insert(oldFile, _item->_renameTarget);
|
||||
if (!PropagateRemoteMove::adjustSelectiveSync(propagator()->_journal, oldFile, _item->_renameTarget)) {
|
||||
done(SyncFileItem::FatalError, tr("Failed to rename file"));
|
||||
done(SyncFileItem::FatalError, tr("Failed to rename file"), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (pinState != PinState::Inherited && !vfs->setPinState(_item->_renameTarget, pinState)) {
|
||||
done(SyncFileItem::NormalError, tr("Error setting pin state"), ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
|
||||
propagator()->_journal->commit("localRename");
|
||||
|
||||
done(SyncFileItem::Success);
|
||||
done(SyncFileItem::Success, {}, ErrorCategory::NoError);
|
||||
}
|
||||
|
||||
bool PropagateLocalRename::deleteOldDbRecord(const QString &fileName)
|
||||
{
|
||||
if (SyncJournalFileRecord oldRecord; !propagator()->_journal->getFileRecord(fileName, &oldRecord)) {
|
||||
qCWarning(lcPropagateLocalRename) << "could not get file from local DB" << fileName;
|
||||
done(SyncFileItem::NormalError, tr("could not get file %1 from local DB").arg(fileName));
|
||||
done(SyncFileItem::NormalError, tr("could not get file %1 from local DB").arg(fileName), OCC::ErrorCategory::GenericError);
|
||||
return false;
|
||||
}
|
||||
if (!propagator()->_journal->deleteFileRecord(fileName)) {
|
||||
qCWarning(lcPropagateLocalRename) << "could not delete file from local DB" << fileName;
|
||||
done(SyncFileItem::NormalError, tr("Could not delete file record %1 from local DB").arg(fileName));
|
||||
done(SyncFileItem::NormalError, tr("Could not delete file record %1 from local DB").arg(fileName), OCC::ErrorCategory::GenericError);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -379,7 +379,7 @@ void OCC::SyncEngine::slotItemDiscovered(const OCC::SyncFileItemPtr &item)
|
|||
item->_status = SyncFileItem::Status::NormalError;
|
||||
item->_instruction = CSYNC_INSTRUCTION_ERROR;
|
||||
item->_errorString = tr("Could not update file: %1").arg(result.error());
|
||||
emit itemCompleted(item);
|
||||
emit itemCompleted(item, ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -391,14 +391,14 @@ void OCC::SyncEngine::slotItemDiscovered(const OCC::SyncFileItemPtr &item)
|
|||
item->_status = SyncFileItem::Status::NormalError;
|
||||
item->_instruction = CSYNC_INSTRUCTION_ERROR;
|
||||
item->_errorString = tr("Could not update virtual file metadata: %1").arg(r.error());
|
||||
emit itemCompleted(item);
|
||||
emit itemCompleted(item, ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!FileSystem::setModTime(filePath, item->_modtime)) {
|
||||
item->_instruction = CSYNC_INSTRUCTION_ERROR;
|
||||
item->_errorString = tr("Could not update file metadata: %1").arg(filePath);
|
||||
emit itemCompleted(item);
|
||||
emit itemCompleted(item, ErrorCategory::GenericError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -412,7 +412,7 @@ void OCC::SyncEngine::slotItemDiscovered(const OCC::SyncFileItemPtr &item)
|
|||
}
|
||||
|
||||
// This might have changed the shared flag, so we must notify SyncFileStatusTracker for example
|
||||
emit itemCompleted(item);
|
||||
emit itemCompleted(item, ErrorCategory::NoError);
|
||||
} else {
|
||||
// Update only outdated data from the disk.
|
||||
|
||||
|
@ -516,7 +516,7 @@ void SyncEngine::startSync()
|
|||
if (!QDir(_localPath).exists()) {
|
||||
_anotherSyncNeeded = DelayedFollowUp;
|
||||
// No _tr, it should only occur in non-mirall
|
||||
Q_EMIT syncError(QStringLiteral("Unable to find local sync folder."));
|
||||
Q_EMIT syncError(QStringLiteral("Unable to find local sync folder."), ErrorCategory::GenericError);
|
||||
finalize(false);
|
||||
return;
|
||||
}
|
||||
|
@ -533,7 +533,7 @@ void SyncEngine::startSync()
|
|||
"Placeholders are postfixed with file sizes using Utility::octetsToString()")
|
||||
.arg(
|
||||
Utility::octetsToString(freeBytes),
|
||||
Utility::octetsToString(minFree)));
|
||||
Utility::octetsToString(minFree)), ErrorCategory::GenericError);
|
||||
finalize(false);
|
||||
return;
|
||||
} else {
|
||||
|
@ -562,7 +562,7 @@ void SyncEngine::startSync()
|
|||
// This creates the DB if it does not exist yet.
|
||||
if (!_journal->open()) {
|
||||
qCWarning(lcEngine) << "No way to create a sync journal!";
|
||||
Q_EMIT syncError(tr("Unable to open or create the local sync database. Make sure you have write access in the sync folder."));
|
||||
Q_EMIT syncError(tr("Unable to open or create the local sync database. Make sure you have write access in the sync folder."), ErrorCategory::GenericError);
|
||||
finalize(false);
|
||||
return;
|
||||
// database creation error!
|
||||
|
@ -578,7 +578,7 @@ void SyncEngine::startSync()
|
|||
_lastLocalDiscoveryStyle = _localDiscoveryStyle;
|
||||
|
||||
if (_syncOptions._vfs->mode() == Vfs::WithSuffix && _syncOptions._vfs->fileSuffix().isEmpty()) {
|
||||
Q_EMIT syncError(tr("Using virtual files with suffix, but suffix is not set"));
|
||||
Q_EMIT syncError(tr("Using virtual files with suffix, but suffix is not set"), ErrorCategory::GenericError);
|
||||
finalize(false);
|
||||
return;
|
||||
}
|
||||
|
@ -590,7 +590,7 @@ void SyncEngine::startSync()
|
|||
qCInfo(lcEngine) << (usingSelectiveSync ? "Using Selective Sync" : "NOT Using Selective Sync");
|
||||
} else {
|
||||
qCWarning(lcEngine) << "Could not retrieve selective sync list from DB";
|
||||
Q_EMIT syncError(tr("Unable to read the blacklist from the local database"));
|
||||
Q_EMIT syncError(tr("Unable to read the blacklist from the local database"), ErrorCategory::GenericError);
|
||||
finalize(false);
|
||||
return;
|
||||
}
|
||||
|
@ -631,7 +631,7 @@ void SyncEngine::startSync()
|
|||
_discoveryPhase->setSelectiveSyncWhiteList(_journal->getSelectiveSyncList(SyncJournalDb::SelectiveSyncWhiteList, &ok));
|
||||
if (!ok) {
|
||||
qCWarning(lcEngine) << "Unable to read selective sync list, aborting.";
|
||||
Q_EMIT syncError(tr("Unable to read from the sync journal."));
|
||||
Q_EMIT syncError(tr("Unable to read from the sync journal."), ErrorCategory::GenericError);
|
||||
finalize(false);
|
||||
return;
|
||||
}
|
||||
|
@ -654,8 +654,8 @@ void SyncEngine::startSync()
|
|||
|
||||
connect(_discoveryPhase.data(), &DiscoveryPhase::itemDiscovered, this, &SyncEngine::slotItemDiscovered);
|
||||
connect(_discoveryPhase.data(), &DiscoveryPhase::newBigFolder, this, &SyncEngine::newBigFolder);
|
||||
connect(_discoveryPhase.data(), &DiscoveryPhase::fatalError, this, [this](const QString &errorString) {
|
||||
Q_EMIT syncError(errorString);
|
||||
connect(_discoveryPhase.data(), &DiscoveryPhase::fatalError, this, [this](const QString &errorString, ErrorCategory errorCategory) {
|
||||
Q_EMIT syncError(errorString, errorCategory);
|
||||
finalize(false);
|
||||
});
|
||||
connect(_discoveryPhase.data(), &DiscoveryPhase::finished, this, &SyncEngine::slotDiscoveryFinished);
|
||||
|
@ -760,7 +760,7 @@ void SyncEngine::slotDiscoveryFinished()
|
|||
// Sanity check
|
||||
if (!_journal->open()) {
|
||||
qCWarning(lcEngine) << "Bailing out, DB failure";
|
||||
Q_EMIT syncError(tr("Cannot open the sync journal"));
|
||||
Q_EMIT syncError(tr("Cannot open the sync journal"), ErrorCategory::GenericError);
|
||||
finalize(false);
|
||||
return;
|
||||
} else {
|
||||
|
@ -892,9 +892,9 @@ void SyncEngine::slotDiscoveryFinished()
|
|||
finish();
|
||||
}
|
||||
|
||||
void SyncEngine::slotCleanPollsJobAborted(const QString &error)
|
||||
void SyncEngine::slotCleanPollsJobAborted(const QString &error, const ErrorCategory errorCategory)
|
||||
{
|
||||
syncError(error);
|
||||
syncError(error, errorCategory);
|
||||
finalize(false);
|
||||
}
|
||||
|
||||
|
@ -914,12 +914,12 @@ void SyncEngine::setNetworkLimits(int upload, int download)
|
|||
}
|
||||
}
|
||||
|
||||
void SyncEngine::slotItemCompleted(const SyncFileItemPtr &item)
|
||||
void SyncEngine::slotItemCompleted(const SyncFileItemPtr &item, const ErrorCategory category)
|
||||
{
|
||||
_progressInfo->setProgressComplete(*item);
|
||||
|
||||
emit transmissionProgress(*_progressInfo);
|
||||
emit itemCompleted(item);
|
||||
emit itemCompleted(item, category);
|
||||
}
|
||||
|
||||
void SyncEngine::slotPropagationFinished(bool success)
|
||||
|
@ -1211,7 +1211,7 @@ void SyncEngine::slotSummaryError(const QString &message)
|
|||
return;
|
||||
|
||||
_uniqueErrors.insert(message);
|
||||
emit syncError(message, ErrorCategory::Normal);
|
||||
emit syncError(message, ErrorCategory::GenericError);
|
||||
}
|
||||
|
||||
void SyncEngine::slotInsufficientLocalStorage()
|
||||
|
|
|
@ -163,16 +163,16 @@ signals:
|
|||
void aboutToPropagate(OCC::SyncFileItemVector &);
|
||||
|
||||
// after each item completed by a job (successful or not)
|
||||
void itemCompleted(const OCC::SyncFileItemPtr &);
|
||||
void itemCompleted(const OCC::SyncFileItemPtr &item, const OCC::ErrorCategory category);
|
||||
|
||||
void transmissionProgress(const OCC::ProgressInfo &progress);
|
||||
|
||||
void itemDiscovered(const OCC::SyncFileItemPtr &);
|
||||
|
||||
/// We've produced a new sync error of a type.
|
||||
void syncError(const QString &message, OCC::ErrorCategory category = OCC::ErrorCategory::Normal);
|
||||
void syncError(const QString &message, const OCC::ErrorCategory category);
|
||||
|
||||
void addErrorToGui(OCC::SyncFileItem::Status status, const QString &errorMessage, const QString &subject);
|
||||
void addErrorToGui(const OCC::SyncFileItem::Status status, const QString &errorMessage, const QString &subject, const OCC::ErrorCategory category);
|
||||
|
||||
void finished(bool success);
|
||||
void started();
|
||||
|
@ -208,11 +208,11 @@ private slots:
|
|||
*/
|
||||
void slotNewItem(const OCC::SyncFileItemPtr &item);
|
||||
|
||||
void slotItemCompleted(const OCC::SyncFileItemPtr &item);
|
||||
void slotItemCompleted(const OCC::SyncFileItemPtr &item, const OCC::ErrorCategory category);
|
||||
void slotDiscoveryFinished();
|
||||
void slotPropagationFinished(bool success);
|
||||
void slotProgress(const OCC::SyncFileItem &item, qint64 curent);
|
||||
void slotCleanPollsJobAborted(const QString &error);
|
||||
void slotCleanPollsJobAborted(const QString &error, const OCC::ErrorCategory category);
|
||||
|
||||
/** Records that a file was touched by a job. */
|
||||
void slotAddTouchedFile(const QString &fn);
|
||||
|
|
|
@ -355,7 +355,7 @@ OCC::CfApiWrapper::PlaceHolderInfo::PlaceHolderInfo(CF_PLACEHOLDER_BASIC_INFO *d
|
|||
{
|
||||
}
|
||||
|
||||
OCC::Optional<OCC::PinStateEnums::PinState> OCC::CfApiWrapper::PlaceHolderInfo::pinState() const
|
||||
OCC::Optional<OCC::PinState> OCC::CfApiWrapper::PlaceHolderInfo::pinState() const
|
||||
{
|
||||
Q_ASSERT(_data);
|
||||
if (!_data) {
|
||||
|
@ -682,7 +682,7 @@ OCC::CfApiWrapper::PlaceHolderInfo OCC::CfApiWrapper::findPlaceholderInfo(const
|
|||
}
|
||||
}
|
||||
|
||||
OCC::Result<OCC::Vfs::ConvertToPlaceholderResult, QString> OCC::CfApiWrapper::setPinState(const QString &path, OCC::PinStateEnums::PinState state, SetPinRecurseMode mode)
|
||||
OCC::Result<OCC::Vfs::ConvertToPlaceholderResult, QString> OCC::CfApiWrapper::setPinState(const QString &path, OCC::PinState state, SetPinRecurseMode mode)
|
||||
{
|
||||
const auto cfState = pinStateToCfPinState(state);
|
||||
const auto flags = pinRecurseModeToCfSetPinFlags(mode);
|
||||
|
|
|
@ -456,6 +456,17 @@ public:
|
|||
QVERIFY(index.isValid());
|
||||
}
|
||||
|
||||
void testActivityAdd(void(OCC::ActivityListModel::*addingMethod)(const OCC::Activity&, OCC::ActivityListModel::ErrorType), OCC::Activity &activity, OCC::ActivityListModel::ErrorType type) {
|
||||
const auto model = testingALM();
|
||||
QCOMPARE(model->rowCount(), 0);
|
||||
|
||||
(model.data()->*addingMethod)(activity, type);
|
||||
QCOMPARE(model->rowCount(), 1);
|
||||
|
||||
const auto index = model->index(0, 0);
|
||||
QVERIFY(index.isValid());
|
||||
}
|
||||
|
||||
private slots:
|
||||
void initTestCase()
|
||||
{
|
||||
|
@ -555,7 +566,7 @@ private slots:
|
|||
};
|
||||
|
||||
void testAddError() {
|
||||
testActivityAdd(&TestingALM::addErrorToActivityList, testSyncResultErrorActivity);
|
||||
testActivityAdd(&TestingALM::addErrorToActivityList, testSyncResultErrorActivity, OCC::ActivityListModel::ErrorType::SyncError);
|
||||
};
|
||||
|
||||
void testAddIgnoredFile() {
|
||||
|
@ -615,7 +626,7 @@ private slots:
|
|||
model->addSyncFileItemToActivityList(testSyncFileItemActivity);
|
||||
QCOMPARE(model->rowCount(), 51);
|
||||
|
||||
model->addErrorToActivityList(testSyncResultErrorActivity);
|
||||
model->addErrorToActivityList(testSyncResultErrorActivity, OCC::ActivityListModel::ErrorType::SyncError);
|
||||
QCOMPARE(model->rowCount(), 52);
|
||||
|
||||
model->addIgnoredFileToList(testFileIgnoredActivity);
|
||||
|
|
Loading…
Reference in a new issue