Propagator: Don't abort sync on error 503
authorOlivier Goffart <ogoffart@woboq.com>
Wed, 20 Jun 2018 13:46:58 +0000 (15:46 +0200)
committerKevin Ottens <kevin.ottens@nextcloud.com>
Tue, 15 Dec 2020 09:58:27 +0000 (10:58 +0100)
Only do it when it is actually a maintenance mode

Issues #5088, #5859, https://github.com/owncloud/enterprise/issues/2637

src/libsync/owncloudpropagator_p.h
src/libsync/propagatedownload.cpp
src/libsync/propagateupload.cpp
test/testsyncengine.cpp

index 90841e53796b308bd8e730833fc81fce21059e95..042ec545ee503bb4908e62ce9c6a8d42baf884cc 100644 (file)
@@ -59,8 +59,7 @@ inline QByteArray getEtagFromReply(QNetworkReply *reply)
  * Given an error from the network, map to a SyncFileItem::Status error
  */
 inline SyncFileItem::Status classifyError(QNetworkReply::NetworkError nerror,
-    int httpCode,
-    bool *anotherSyncNeeded = nullptr)
+    int httpCode, bool *anotherSyncNeeded = nullptr, const QByteArray &errorBody = QByteArray())
 {
     Q_ASSERT(nerror != QNetworkReply::NoError); // we should only be called when there is an error
 
@@ -76,9 +75,10 @@ inline SyncFileItem::Status classifyError(QNetworkReply::NetworkError nerror,
     }
 
     if (httpCode == 503) {
-        // "Service unavailable"
-        // Happens for maintenance mode and other temporary outages
-        return SyncFileItem::FatalError;
+        // When the server is in maintenance mode, we want to exit the sync immediatly
+        // so that we do not flood the server with many requests
+        return errorBody.contains(R"(>Sabre\DAV\Exception\ServiceUnavailable<)") ?
+            SyncFileItem::FatalError : SyncFileItem::NormalError;
     }
 
     if (httpCode == 412) {
index 6e930848ea72e160f1ed02be154ed21462ee4568..2e305762bfd2f374a60dfa1a2795e8e34827fc5c 100644 (file)
@@ -689,13 +689,16 @@ void PropagateDownloadFile::slotGetFinished()
             propagator()->_journal->avoidReadFromDbOnNextSync(_item->_file);
         }
 
+        QByteArray errorBody;
+        QString errorString = _item->_httpErrorCode >= 400 ? job->errorStringParsingBody(&errorBody)
+                                                           : job->errorString();
         SyncFileItem::Status status = job->errorStatus();
         if (status == SyncFileItem::NoStatus) {
             status = classifyError(err, _item->_httpErrorCode,
-                &propagator()->_anotherSyncNeeded);
+                &propagator()->_anotherSyncNeeded, errorBody);
         }
 
-        done(status,_item->_httpErrorCode >= 400 ? job->errorStringParsingBody() : job->errorString());
+        done(status, errorString);
         return;
     }
 
index ac83b5c9f242fcd893ed09a51789aca3e1c92148..1908136fdef42535ab19023545a5cd77c062ebec 100644 (file)
@@ -651,7 +651,7 @@ void PropagateUploadFileCommon::commonErrorHandling(AbstractNetworkJob *job)
     checkResettingErrors();
 
     SyncFileItem::Status status = classifyError(job->reply()->error(), _item->_httpErrorCode,
-        &propagator()->_anotherSyncNeeded);
+        &propagator()->_anotherSyncNeeded, replyContent);
 
     // Insufficient remote storage.
     if (_item->_httpErrorCode == 507) {
index 193b8189d8fa6178779a031dc5411afc75eb03a4..cc557baa36d8e2ebc92458b00169d723a399102a 100644 (file)
@@ -239,8 +239,8 @@ private slots:
         fakeFolder.remoteModifier().insert("Y/Z/d7");
         fakeFolder.remoteModifier().insert("Y/Z/d8");
         fakeFolder.remoteModifier().insert("Y/Z/d9");
-        fakeFolder.serverErrorPaths().append("Y/Z/d2", 503); // 503 is a fatal error
-        fakeFolder.serverErrorPaths().append("Y/Z/d3", 503); // 503 is a fatal error
+        fakeFolder.serverErrorPaths().append("Y/Z/d2", 503);
+        fakeFolder.serverErrorPaths().append("Y/Z/d3", 503);
         QVERIFY(!fakeFolder.syncOnce());
         QCoreApplication::processEvents(); // should not crash
 
@@ -251,12 +251,12 @@ private slots:
             QVERIFY(!seen.contains(item->_file)); // signal only sent once per item
             seen.insert(item->_file);
             if (item->_file == "Y/Z/d2") {
-                QVERIFY(item->_status == SyncFileItem::FatalError);
-            } else if(item->_file == "Y/Z/d3") {
+                QVERIFY(item->_status == SyncFileItem::NormalError);
+            } else if (item->_file == "Y/Z/d3") {
                 QVERIFY(item->_status != SyncFileItem::Success);
+            } else if (!item->isDirectory()) {
+                QVERIFY(item->_status == SyncFileItem::Success);
             }
-            // We do not know about the other files - maybe the sync was aborted,
-            // maybe they finished before the error caused the abort.
         }
     }