1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
#include "./internalerror.h"
#include "./syncthinglauncher.h"
#if defined(SYNCTHINGWIDGETS_GUI_QTWIDGETS)
#include "../settings/settings.h"
#endif
#include <syncthingconnector/syncthingconnection.h>
#include <syncthingconnector/syncthingservice.h>
#include <QNetworkReply>
using namespace Data;
namespace QtGui {
/*!
* \brief Returns whether to ignore inavailability after start or standby-wakeup.
*/
static bool ignoreInavailabilityAfterStart(unsigned int ignoreInavailabilityAfterStartSec, const SyncthingLauncher *launcher,
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
const SyncthingService *service,
#endif
const QString &message, int networkError)
{
if (!ignoreInavailabilityAfterStartSec) {
return false;
}
// ignore only certain types of errors
// note: Not sure how to check for "Forbidden" except for checking the error message.
switch (networkError) {
case QNetworkReply::ConnectionRefusedError:
case QNetworkReply::HostNotFoundError:
case QNetworkReply::TemporaryNetworkFailureError:
case QNetworkReply::NetworkSessionFailedError:
case QNetworkReply::ProxyConnectionRefusedError:
case QNetworkReply::ProxyNotFoundError:
break;
default:
if (message.contains(QLatin1String("Forbidden"))) {
break;
}
return false;
};
// ignore inavailable shorty after the start
if ((launcher && launcher->isRunning())
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
&& ((service && service->isSystemdAvailable()
&& !service->isActiveWithoutSleepFor(launcher->activeSince(), ignoreInavailabilityAfterStartSec))
|| !launcher->isActiveWithoutSleepFor(ignoreInavailabilityAfterStartSec))
#else
&& !launcher->isActiveWithoutSleepFor(ignoreInavailabilityAfterStartSec)
#endif
) {
return true;
}
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
if (service && !service->isActiveWithoutSleepFor(ignoreInavailabilityAfterStartSec)) {
return true;
}
#endif
return false;
}
/*!
* \brief Returns whether the error is relevant. Only in this case a notification for the error should be shown.
* \todo Unify with SyncthingNotifier::isDisconnectRelevant().
*/
bool InternalError::isRelevant(
const SyncthingConnection &connection, SyncthingErrorCategory category, const QString &message, int networkError, bool useGlobalSettings)
{
// ignore overall connection errors when auto reconnect tries >= 1
if (category != SyncthingErrorCategory::OverallConnection && category != SyncthingErrorCategory::TLS && connection.autoReconnectTries() >= 1) {
return false;
}
// skip further considerations if connection is remote
if (!connection.syncthingUrl().isEmpty() && !connection.isLocal()) {
return true;
}
// define default settings
constexpr auto considerForReconnectDefault = true;
constexpr auto ignoreInavailabilityAfterStartSecDefault = 15;
#if defined(SYNCTHINGWIDGETS_GUI_QTWIDGETS)
// ignore configuration errors on first launch (to avoid greeting people with an error message)
const auto &settings = Settings::values();
if ((settings.firstLaunch || settings.fakeFirstLaunch)
&& (category == SyncthingErrorCategory::OverallConnection && networkError == QNetworkReply::NoError)) {
return false;
}
// decide based on global user settings what to consider
const auto considerLauncherForReconnect = useGlobalSettings ? settings.launcher.considerForReconnect : considerForReconnectDefault;
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
const auto considerServiceForReconnect = useGlobalSettings ? settings.systemd.considerForReconnect : considerForReconnectDefault;
#endif
const auto ignoreInavailabilityAfterStartSec
= useGlobalSettings ? settings.ignoreInavailabilityAfterStart : ignoreInavailabilityAfterStartSecDefault;
#else
// use always the default settings when not building with Qt Widgets GUI at all
Q_UNUSED(useGlobalSettings)
constexpr auto considerLauncherForReconnect = considerForReconnectDefault;
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
constexpr auto considerServiceForReconnect = considerForReconnectDefault;
#endif
constexpr auto ignoreInavailabilityAfterStartSec = ignoreInavailabilityAfterStartSecDefault;
#endif
// consider process/launcher or systemd unit status
const auto remoteHostClosed = networkError == QNetworkReply::ConnectionRefusedError || networkError == QNetworkReply::RemoteHostClosedError
|| networkError == QNetworkReply::ProxyConnectionClosedError;
// ignore "remote host closed" error if we've just stopped Syncthing ourselves (or "connection refused" which can also be the result of stopping Syncthing ourselves)
const auto *launcher = SyncthingLauncher::mainInstance();
if (considerLauncherForReconnect && remoteHostClosed && launcher && launcher->isManuallyStopped()) {
return false;
}
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
const auto *const service = SyncthingService::mainInstance();
if (considerServiceForReconnect && remoteHostClosed && service && service->isManuallyStopped()) {
return false;
}
#endif
return !ignoreInavailabilityAfterStart(ignoreInavailabilityAfterStartSec, launcher,
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
service,
#endif
message, networkError);
}
} // namespace QtGui
|