File: internalerror.cpp

package info (click to toggle)
syncthingtray 1.7.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 6,804 kB
  • sloc: cpp: 31,085; xml: 1,694; java: 570; sh: 81; javascript: 53; makefile: 25
file content (135 lines) | stat: -rw-r--r-- 5,465 bytes parent folder | download
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