diff --git a/services/sync/modules/service.js b/services/sync/modules/service.js index 0ca86718672..6eb81858020 100644 --- a/services/sync/modules/service.js +++ b/services/sync/modules/service.js @@ -1657,7 +1657,7 @@ WeaveSvc.prototype = { * Array of engine names to wipe. If not given, all engines are used. */ wipeClient: function WeaveSvc_wipeClient(engines) - this._catch(this._notify("wipe-client", "", function() { + this._notify("wipe-client", "", function() { // If we don't have any engines, reset the service and wipe all engines if (!engines) { // Clear out any service data @@ -1676,7 +1676,7 @@ WeaveSvc.prototype = { // Save the password/passphrase just in-case they aren't restored by sync this.persistLogin(); - }))(), + })(), /** * Wipe all remote user data by wiping the server then telling each remote @@ -1685,8 +1685,8 @@ WeaveSvc.prototype = { * @param engines [optional] * Array of engine names to wipe. If not given, all engines are used. */ - wipeRemote: function WeaveSvc_wipeRemote(engines) - this._catch(this._notify("wipe-remote", "", function() { + wipeRemote: function wipeRemote(engines) { + try { // Make sure stuff gets uploaded. this.resetClient(engines); @@ -1704,7 +1704,11 @@ WeaveSvc.prototype = { // Make sure the changed clients get updated. Clients.sync(); - }))(), + } catch (ex) { + ErrorHandler.checkServerError(ex); + throw ex; + } + }, /** * Reset local service information like logs, sync times, caches. diff --git a/services/sync/tests/unit/test_errorhandler.js b/services/sync/tests/unit/test_errorhandler.js index 93e06f8faa6..35732c654b2 100644 --- a/services/sync/tests/unit/test_errorhandler.js +++ b/services/sync/tests/unit/test_errorhandler.js @@ -30,7 +30,9 @@ CatapultEngine.prototype = { __proto__: SyncEngine.prototype, exception: null, // tests fill this in _sync: function _sync() { - throw this.exception; + if (this.exception) { + throw this.exception; + } } }; @@ -68,7 +70,9 @@ function sync_httpd_setup() { syncID: Service.syncID, storageVersion: STORAGE_VERSION, engines: {clients: {version: Clients.version, - syncID: Clients.syncID}} + syncID: Clients.syncID}, + catapult: {version: Engines.get("catapult").version, + syncID: Engines.get("catapult").syncID}} }); let clientsColl = new ServerCollection({}, true); @@ -106,7 +110,9 @@ function sync_httpd_setup() { "/maintenance/1.1/broken.wipe/storage/meta/global": upd("meta", global.handler()), "/maintenance/1.1/broken.wipe/storage/crypto/keys": upd("crypto", (new ServerWBO("keys")).handler()), - "/maintenance/1.1/broken.wipe/storage": service_unavailable + "/maintenance/1.1/broken.wipe/storage": service_unavailable, + "/maintenance/1.1/broken.wipe/storage/clients": upd("clients", clientsColl.handler()), + "/maintenance/1.1/broken.wipe/storage/catapult": service_unavailable }); } @@ -115,7 +121,10 @@ function setUp() { Service.password = "ilovejane"; Service.passphrase = "abcdeabcdeabcdeabcdeabcdea"; Service.clusterURL = "http://localhost:8080/"; + return generateAndUploadKeys(); +} +function generateAndUploadKeys() { generateNewKeys(); let serverKeys = CollectionKeys.asWBO("crypto", "keys"); serverKeys.encrypt(Service.syncKeyBundle); @@ -1039,7 +1048,8 @@ add_test(function test_upload_crypto_keys_login_prolonged_server_maintenance_err }); add_test(function test_wipeServer_login_prolonged_server_maintenance_error(){ - // Test crypto/keys prolonged server maintenance errors are reported. + // Test that we report prolonged server maintenance errors that occur whilst + // wiping the server. let server = sync_httpd_setup(); // Start off with an empty account, do not upload a key. @@ -1072,6 +1082,47 @@ add_test(function test_wipeServer_login_prolonged_server_maintenance_error(){ Service.sync(); }); +add_test(function test_wipeRemote_prolonged_server_maintenance_error(){ + // Test that we report prolonged server maintenance errors that occur whilst + // wiping all remote devices. + let server = sync_httpd_setup(); + + Service.username = "broken.wipe"; + Service.password = "ilovejane"; + Service.passphrase = "abcdeabcdeabcdeabcdeabcdea"; + Service.clusterURL = "http://localhost:8080/maintenance/"; + generateAndUploadKeys(); + + let engine = Engines.get("catapult"); + engine.exception = null; + engine.enabled = true; + + let backoffInterval; + Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) { + Svc.Obs.remove("weave:service:backoff:interval", observe); + backoffInterval = subject; + }); + + Svc.Obs.add("weave:ui:sync:error", function onUIUpdate() { + Svc.Obs.remove("weave:ui:sync:error", onUIUpdate); + do_check_true(Status.enforceBackoff); + do_check_eq(backoffInterval, 42); + do_check_eq(Status.service, SYNC_FAILED); + do_check_eq(Status.sync, PROLONGED_SYNC_FAILURE); + do_check_eq(Svc.Prefs.get("firstSync"), "wipeRemote"); + + clean(); + server.stop(run_next_test); + }); + + do_check_false(Status.enforceBackoff); + do_check_eq(Status.service, STATUS_OK); + + Svc.Prefs.set("firstSync", "wipeRemote"); + setLastSync(PROLONGED_ERROR_DURATION); + Service.sync(); +}); + add_test(function test_sync_syncAndReportErrors_server_maintenance_error() { // Test server maintenance errors are reported // when calling syncAndReportErrors. @@ -1270,6 +1321,47 @@ add_test(function test_wipeServer_login_syncAndReportErrors_server_maintenance_e ErrorHandler.syncAndReportErrors(); }); +add_test(function test_wipeRemote_syncAndReportErrors_server_maintenance_error(){ + // Test that we report prolonged server maintenance errors that occur whilst + // wiping all remote devices. + let server = sync_httpd_setup(); + + Service.username = "broken.wipe"; + Service.password = "ilovejane"; + Service.passphrase = "abcdeabcdeabcdeabcdeabcdea"; + Service.clusterURL = "http://localhost:8080/maintenance/"; + generateAndUploadKeys(); + + let engine = Engines.get("catapult"); + engine.exception = null; + engine.enabled = true; + + let backoffInterval; + Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) { + Svc.Obs.remove("weave:service:backoff:interval", observe); + backoffInterval = subject; + }); + + Svc.Obs.add("weave:ui:sync:error", function onUIUpdate() { + Svc.Obs.remove("weave:ui:sync:error", onUIUpdate); + do_check_true(Status.enforceBackoff); + do_check_eq(backoffInterval, 42); + do_check_eq(Status.service, SYNC_FAILED); + do_check_eq(Status.sync, SERVER_MAINTENANCE); + do_check_eq(Svc.Prefs.get("firstSync"), "wipeRemote"); + + clean(); + server.stop(run_next_test); + }); + + do_check_false(Status.enforceBackoff); + do_check_eq(Status.service, STATUS_OK); + + Svc.Prefs.set("firstSync", "wipeRemote"); + setLastSync(NON_PROLONGED_ERROR_DURATION); + ErrorHandler.syncAndReportErrors(); +}); + add_test(function test_sync_syncAndReportErrors_prolonged_server_maintenance_error() { // Test prolonged server maintenance errors are // reported when calling syncAndReportErrors.