Bug 1340357 - remove all special eslint rules in services/. r=eoger
authorMark Hammond <mhammond@skippinet.com.au>
Fri, 17 Feb 2017 12:34:45 +1100
changeset 343506 b6118fb4d0395e1bd86fb9621ca42cf73b4d84c8
parent 343505 5c217cd4e9dc2028c987b2d8719c49d22d82bbf6
child 343507 88736bccd9516b8ccc7197a8e843358f099eafb8
push id31381
push userkwierso@gmail.com
push dateFri, 17 Feb 2017 20:45:51 +0000
treeherdermozilla-central@f302def88fe5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerseoger
bugs1340357
milestone54.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1340357 - remove all special eslint rules in services/. r=eoger MozReview-Commit-ID: 6zMOBoWLOhJ
services/.eslintrc.js
services/common/blocklist-clients.js
services/common/hawkclient.js
services/common/kinto-storage-adapter.js
services/common/modules-testing/storageserver.js
services/common/utils.js
services/fxaccounts/FxAccounts.jsm
services/fxaccounts/FxAccountsConfig.jsm
services/fxaccounts/FxAccountsManager.jsm
services/fxaccounts/FxAccountsOAuthGrantClient.jsm
services/fxaccounts/FxAccountsProfileClient.jsm
services/fxaccounts/FxAccountsPush.js
services/fxaccounts/FxAccountsStorage.jsm
services/fxaccounts/FxAccountsWebChannel.jsm
services/fxaccounts/tests/xpcshell/test_client.js
services/sync/modules-testing/rotaryengine.js
services/sync/modules/browserid_identity.js
services/sync/modules/engines.js
services/sync/modules/engines/bookmarks.js
services/sync/modules/engines/forms.js
services/sync/modules/record.js
services/sync/modules/service.js
services/sync/tests/unit/test_addon_utils.js
services/sync/tests/unit/test_addons_store.js
services/sync/tests/unit/test_fxa_node_reassignment.js
services/sync/tests/unit/test_hmac_error.js
services/sync/tests/unit/test_node_reassignment.js
services/sync/tests/unit/test_password_store.js
services/sync/tps/extensions/tps/resource/modules/forms.jsm
deleted file mode 100644
--- a/services/.eslintrc.js
+++ /dev/null
@@ -1,16 +0,0 @@
-"use strict";
-
-module.exports = {
-  "extends": [
-    "../toolkit/.eslintrc.js"
-  ],
-  rules: {
-    /* These rules are only set to warn temporarily
-       until they get fixed, at which point their
-       respective line in this file should be removed. */
-    "consistent-return": "warn",
-    "no-func-assign": "warn",
-    "no-nested-ternary": "warn",
-    "no-undef": "error",
-  }
-};
--- a/services/common/blocklist-clients.js
+++ b/services/common/blocklist-clients.js
@@ -59,17 +59,22 @@ function mergeChanges(collection, localR
   localRecords.forEach((record) => records[record.id] = collection.cleanLocalFields(record));
   // All existing records are replaced by the version from the server.
   changes.forEach((record) => records[record.id] = record);
 
   return Object.values(records)
     // Filter out deleted records.
     .filter((record) => record.deleted != true)
     // Sort list by record id.
-    .sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0);
+    .sort((a, b) => {
+      if (a.id < b.id) {
+        return -1;
+      }
+      return a.id > b.id ? 1 : 0;
+    });
 }
 
 
 function fetchCollectionMetadata(remote, collection) {
   const client = new KintoHttpClient(remote);
   return client.bucket(collection.bucket).collection(collection.name).getData()
     .then(result => {
       return result.signature;
--- a/services/common/hawkclient.js
+++ b/services/common/hawkclient.js
@@ -235,27 +235,28 @@ this.HawkClient.prototype = {
       // All responses may have backoff headers, which are a server-side safety
       // valve to allow slowing down clients without hurting performance.
       self._maybeNotifyBackoff(restResponse, "x-weave-backoff");
       self._maybeNotifyBackoff(restResponse, "x-backoff");
 
       if (error) {
         // When things really blow up, reconstruct an error object that follows
         // the general format of the server on error responses.
-        return deferred.reject(self._constructError(restResponse, error));
+        deferred.reject(self._constructError(restResponse, error));
+        return;
       }
 
       self._updateClockOffset(restResponse.headers["date"]);
 
       if (status === 401 && retryOK && !("retry-after" in restResponse.headers)) {
         // Retry once if we were rejected due to a bad timestamp.
         // Clock offset is adjusted already in the top of this function.
         log.debug("Received 401 for " + path + ": retrying");
-        return deferred.resolve(
-            self.request(path, method, credentials, payloadObj, extraHeaders, false));
+        deferred.resolve(self.request(path, method, credentials, payloadObj, extraHeaders, false));
+        return;
       }
 
       // If the server returned a json error message, use it in the rejection
       // of the promise.
       //
       // In the case of a 401, in which we are probably being rejected for a
       // bad timestamp, retry exactly once, during which time clock offset will
       // be adjusted.
@@ -263,19 +264,21 @@ this.HawkClient.prototype = {
       let jsonResponse = {};
       try {
         jsonResponse = JSON.parse(restResponse.body);
       } catch (notJSON) {}
 
       let okResponse = (200 <= status && status < 300);
       if (!okResponse || jsonResponse.error) {
         if (jsonResponse.error) {
-          return deferred.reject(jsonResponse);
+          deferred.reject(jsonResponse);
+        } else {
+          deferred.reject(self._constructError(restResponse, "Request failed"));
         }
-        return deferred.reject(self._constructError(restResponse, "Request failed"));
+        return;
       }
       // It's up to the caller to know how to decode the response.
       // We just return the whole response.
       deferred.resolve(this.response);
     }
 
     function onComplete(error) {
       try {
--- a/services/common/kinto-storage-adapter.js
+++ b/services/common/kinto-storage-adapter.js
@@ -283,17 +283,17 @@ class FirefoxAdapter extends Kinto.adapt
 
   get(id) {
     const params = {
       collection_name: this.collection,
       record_id: id,
     };
     return this._executeStatement(statements.getRecord, params).then(result => {
       if (result.length == 0) {
-        return;
+        return null;
       }
       return JSON.parse(result[0].getResultByName("record"));
     });
   }
 
   list(params = { filters: {}, order: "" }) {
     const parameters = {
       collection_name: this.collection,
--- a/services/common/modules-testing/storageserver.js
+++ b/services/common/modules-testing/storageserver.js
@@ -179,21 +179,23 @@ ServerBSO.prototype = {
       }
     }
 
     let input = CommonUtils.readBytesFromInputStream(request.bodyInputStream);
     let parsed;
     try {
       parsed = JSON.parse(input);
     } catch (ex) {
-      return sendMozSvcError(request, response, "8");
+      sendMozSvcError(request, response, "8");
+      return;
     }
 
     if (typeof(parsed) != "object") {
-      return sendMozSvcError(request, response, "8");
+      sendMozSvcError(request, response, "8");
+      return;
     }
 
     // Don't update if a conditional request fails preconditions.
     if (request.hasHeader("x-if-unmodified-since")) {
       let reqModified = parseInt(request.getHeader("x-if-unmodified-since"));
 
       if (reqModified < this.modified) {
         response.setStatusLine(request.httpVersion, 412, "Precondition Failed");
@@ -211,45 +213,45 @@ ServerBSO.prototype = {
     }
 
     // Alert when we see unrecognized fields.
     for (let [key, value] of Object.entries(parsed)) {
       switch (key) {
         case "payload":
           if (typeof(value) != "string") {
             sendMozSvcError(request, response, "8");
-            return true;
+            return;
           }
 
           this.payload = value;
           break;
 
         case "ttl":
           if (!isInteger(value)) {
             sendMozSvcError(request, response, "8");
-            return true;
+            return;
           }
           this.ttl = parseInt(value, 10);
           break;
 
         case "sortindex":
           if (!isInteger(value) || value.length > 9) {
             sendMozSvcError(request, response, "8");
-            return true;
+            return;
           }
           this.sortindex = parseInt(value, 10);
           break;
 
         case "id":
           break;
 
         default:
           this._log.warn("Unexpected field in BSO record: " + key);
           sendMozSvcError(request, response, "8");
-          return true;
+          return;
       }
     }
 
     this.modified = request.timestamp;
     this.deleted = false;
     response.setHeader("X-Last-Modified", "" + this.modified, false);
 
     response.setStatusLine(request.httpVersion, code, status);
@@ -745,26 +747,28 @@ StorageServerCollection.prototype = {
         input = JSON.parse(inputBody);
       } catch (ex) {
         this._log.info("JSON parse error on input body!");
         throw HTTP_400;
       }
 
       if (!Array.isArray(input)) {
         this._log.info("Input JSON type not an array!");
-        return sendMozSvcError(request, response, "8");
+        sendMozSvcError(request, response, "8");
+        return;
       }
     } else if (inputMediaType == "application/newlines") {
       for (let line of inputBody.split("\n")) {
         let record;
         try {
           record = JSON.parse(line);
         } catch (ex) {
           this._log.info("JSON parse error on line!");
-          return sendMozSvcError(request, response, "8");
+          sendMozSvcError(request, response, "8");
+          return;
         }
 
         input.push(record);
       }
     } else {
       this._log.info("Unknown media type: " + inputMediaType);
       throw HTTP_415;
     }
@@ -800,23 +804,26 @@ StorageServerCollection.prototype = {
   },
 
   handler: function handler() {
     let self = this;
 
     return function(request, response) {
       switch (request.method) {
         case "GET":
-          return self.getHandler(request, response);
+          self.getHandler(request, response);
+          return;
 
         case "POST":
-          return self.postHandler(request, response);
+          self.postHandler(request, response);
+          return;
 
         case "DELETE":
-          return self.deleteHandler(request, response);
+          self.deleteHandler(request, response);
+          return;
 
       }
 
       request.setHeader("Allow", "GET,POST,DELETE");
       response.setStatusLine(request.httpVersion, 405, "Method Not Allowed");
     };
   },
 
@@ -1383,17 +1390,18 @@ StorageServer.prototype = {
 
       username = userPath;
     }
 
     // Hand off to the appropriate handler for this path component.
     if (first in this.toplevelHandlers) {
       let handler = this.toplevelHandlers[first];
       try {
-        return handler.call(this, handler, req, resp, version, username, rest);
+        handler.call(this, handler, req, resp, version, username, rest);
+        return;
       } catch (ex) {
         this._log.warn("Got exception during request", ex);
         throw ex;
       }
     }
     this._log.debug("StorageServer: Unknown top-level " + first);
     throw HTTP_404;
   },
@@ -1434,28 +1442,30 @@ StorageServer.prototype = {
           // Tried to GET on a collection that doesn't exist.
           if (!coll) {
             respond(404, "Not Found");
             return;
           }
 
           // No BSO URL parameter goes to collection handler.
           if (!bsoID) {
-            return coll.collectionHandler(req, resp);
+            coll.collectionHandler(req, resp);
+            return;
           }
 
           // Handle non-existent BSO.
           let bso = coll.bso(bsoID);
           if (!bso) {
             respond(404, "Not Found");
             return;
           }
 
           // Proxy to BSO handler.
-          return bso.getHandler(req, resp);
+          bso.getHandler(req, resp);
+          return;
 
         case "DELETE":
           // Collection doesn't exist.
           if (!coll) {
             respond(404, "Not Found");
             return;
           }
 
@@ -1529,27 +1539,29 @@ StorageServer.prototype = {
             if (bsoID) {
               let bso = coll.bso(bsoID);
               if (!bso) {
                 this._log.trace("StorageServer: creating BSO " + collection +
                                 "/" + bsoID);
                 try {
                   bso = coll.insert(bsoID);
                 } catch (ex) {
-                  return sendMozSvcError(req, resp, "8");
+                  sendMozSvcError(req, resp, "8");
+                  return;
                 }
               }
 
               bso.putHandler(req, resp);
 
               coll.timestamp = req.timestamp;
-              return resp;
+              return;
             }
 
-            return coll.collectionHandler(req, resp);
+            coll.collectionHandler(req, resp);
+            return;
           } catch (ex) {
             if (ex instanceof HttpError) {
               if (!collectionExisted) {
                 this.deleteCollection(username, collection);
               }
             }
 
             throw ex;
@@ -1558,26 +1570,30 @@ StorageServer.prototype = {
         default:
           throw new Error("Request method " + req.method + " not implemented.");
       }
     },
 
     "info": function handleInfo(handler, req, resp, version, username, rest) {
       switch (rest) {
         case "collections":
-          return this.handleInfoCollections(req, resp, username);
+          this.handleInfoCollections(req, resp, username);
+          return;
 
         case "collection_counts":
-          return this.handleInfoCounts(req, resp, username);
+          this.handleInfoCounts(req, resp, username);
+          return;
 
         case "collection_usage":
-          return this.handleInfoUsage(req, resp, username);
+          this.handleInfoUsage(req, resp, username);
+          return;
 
         case "quota":
-          return this.handleInfoQuota(req, resp, username);
+          this.handleInfoQuota(req, resp, username);
+          return;
 
         default:
           this._log.warn("StorageServer: Unknown info operation " + rest);
           throw HTTP_404;
       }
     }
   },
 
--- a/services/common/utils.js
+++ b/services/common/utils.js
@@ -156,17 +156,17 @@ this.CommonUtils = {
   namedTimer: function namedTimer(callback, wait, thisObj, name) {
     if (!thisObj || !name) {
       throw "You must provide both an object and a property name for the timer!";
     }
 
     // Delay an existing timer if it exists
     if (name in thisObj && thisObj[name] instanceof Ci.nsITimer) {
       thisObj[name].delay = wait;
-      return;
+      return thisObj[name];
     }
 
     // Create a special timer that we can add extra properties
     let timer = Object.create(Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer));
 
     // Provide an easy way to clear out the timer
     timer.clear = function() {
       thisObj[name] = null;
--- a/services/fxaccounts/FxAccounts.jsm
+++ b/services/fxaccounts/FxAccounts.jsm
@@ -546,16 +546,17 @@ FxAccountsInternal.prototype = {
    *         successfully and is rejected on error.
    */
   setSignedInUser: function setSignedInUser(credentials) {
     log.debug("setSignedInUser - aborting any existing flows");
     return this.getSignedInUser().then(signedInUser => {
       if (signedInUser) {
         return this.deleteDeviceRegistration(signedInUser.sessionToken, signedInUser.deviceId);
       }
+      return null;
     }).then(() =>
       this.abortExistingFlow()
     ).then(() => {
       let currentAccountState = this.currentAccountState = this.newAccountState(
         Cu.cloneInto(credentials, {}) // Pass a clone of the credentials object.
       );
       // This promise waits for storage, but not for verification.
       // We're telling the caller that this is durable now (although is that
@@ -780,16 +781,17 @@ FxAccountsInternal.prototype = {
         Promise.resolve().then(() => {
           // This can happen in the background and shouldn't block
           // the user from signing out. The server must tolerate
           // clients just disappearing, so this call should be best effort.
           if (sessionToken) {
             return this._signOutServer(sessionToken, deviceId);
           }
           log.warn("Missing session token; skipping remote sign out");
+          return null;
         }).catch(err => {
           log.error("Error during remote sign out of Firefox Accounts", err);
         }).then(() => {
           return this._destroyAllOAuthTokens(tokensToRevoke);
         }).catch(err => {
           log.error("Error during destruction of oauth tokens during signout", err);
         }).then(() => {
           FxAccountsConfig.resetConfigURLs();
@@ -1047,17 +1049,18 @@ FxAccountsInternal.prototype = {
     let keyPair;
     if (keyPairValid) {
       keyPair = accountData.keyPair;
     } else {
       let keyWillBeValidUntil = this.now() + KEY_LIFETIME;
       keyPair = yield new Promise((resolve, reject) => {
         jwcrypto.generateKeyPair("DS160", (err, kp) => {
           if (err) {
-            return reject(err);
+            reject(err);
+            return;
           }
           log.debug("got keyPair");
           resolve({
             rawKeyPair: kp,
             validUntil: keyWillBeValidUntil,
           });
         });
       });
@@ -1535,16 +1538,17 @@ FxAccountsInternal.prototype = {
   // Attempt to update the auth server with whatever device details are stored
   // in the account data. Returns a promise that always resolves, never rejects.
   // If the promise resolves to a value, that value is the device id.
   updateDeviceRegistration() {
     return this.getSignedInUser().then(signedInUser => {
       if (signedInUser) {
         return this._registerOrUpdateDevice(signedInUser);
       }
+      return null;
     }).catch(error => this._logErrorAndResetDeviceRegistrationVersion(error));
   },
 
   // Delete the Push Subscription and the device registration on the auth server.
   // Returns a promise that always resolves, never rejects.
   async deleteDeviceRegistration(sessionToken, deviceId) {
     try {
       // Allow tests to skip device registration because it makes remote requests to the auth server.
@@ -1571,25 +1575,26 @@ FxAccountsInternal.prototype = {
   handleDeviceDisconnection(deviceId) {
     return this.currentAccountState.getUserAccountData()
       .then(data => data ? data.deviceId : null)
       .then(localDeviceId => {
         if (!localDeviceId) {
           // We've already been logged out (and that logout is probably what
           // caused us to get here via push!), so don't make noise here.
           log.info(`Push request to disconnect, but we've already disconnected`);
-          return;
+          return null;
         }
         if (deviceId == localDeviceId) {
           this.notifyObservers(ON_DEVICE_DISCONNECTED_NOTIFICATION, deviceId);
           return this.signOut(true);
         }
         log.error(
           `The device ID to disconnect doesn't match with the local device ID. ` +
           `Local: ${localDeviceId}, ID to disconnect: ${deviceId}`);
+        return null;
     });
   },
 
   /**
    * Delete all the cached persisted credentials we store for FxA.
    *
    * @return Promise resolves when the user data has been persisted
   */
--- a/services/fxaccounts/FxAccountsConfig.jsm
+++ b/services/fxaccounts/FxAccountsConfig.jsm
@@ -122,24 +122,26 @@ this.FxAccountsConfig = {
     }
     let configURL = rootURL + "/.well-known/fxa-client-configuration";
     let jsonStr = yield new Promise((resolve, reject) => {
       let request = new RESTRequest(configURL);
       request.setHeader("Accept", "application/json");
       request.get(error => {
         if (error) {
           log.error(`Failed to get configuration object from "${configURL}"`, error);
-          return reject(error);
+          reject(error);
+          return;
         }
         if (!request.response.success) {
           log.error(`Received HTTP response code ${request.response.status} from configuration object request`);
           if (request.response && request.response.body) {
             log.debug("Got error response", request.response.body);
           }
-          return reject(request.response.status);
+          reject(request.response.status);
+          return;
         }
         resolve(request.response.body);
       });
     });
 
     log.debug("Got successful configuration response", jsonStr);
     try {
       // Update the prefs directly specified by the config.
--- a/services/fxaccounts/FxAccountsManager.jsm
+++ b/services/fxaccounts/FxAccountsManager.jsm
@@ -75,17 +75,17 @@ this.FxAccountsManager = {
     if (aDetails) {
       reason.details = aDetails;
     }
     return Promise.reject(reason);
   },
 
   _getError(aServerResponse) {
     if (!aServerResponse || !aServerResponse.error || !aServerResponse.error.errno) {
-      return;
+      return null;
     }
     let error = SERVER_ERRNO_TO_ERROR[aServerResponse.error.errno];
     return error;
   },
 
   _serverError(aServerResponse) {
     let error = this._getError({ error: aServerResponse });
     return this._error(error ? error : ERROR_SERVER_ERROR, aServerResponse);
--- a/services/fxaccounts/FxAccountsOAuthGrantClient.jsm
+++ b/services/fxaccounts/FxAccountsOAuthGrantClient.jsm
@@ -137,54 +137,57 @@ this.FxAccountsOAuthGrantClient.prototyp
       let request = new this._Request(profileDataUrl);
       method = method.toUpperCase();
 
       request.setHeader("Accept", "application/json");
       request.setHeader("Content-Type", "application/json");
 
       request.onComplete = function(error) {
         if (error) {
-          return reject(new FxAccountsOAuthGrantClientError({
+          reject(new FxAccountsOAuthGrantClientError({
             error: ERROR_NETWORK,
             errno: ERRNO_NETWORK,
             message: error.toString(),
           }));
+          return;
         }
 
         let body = null;
         try {
           body = JSON.parse(request.response.body);
         } catch (e) {
-          return reject(new FxAccountsOAuthGrantClientError({
+          reject(new FxAccountsOAuthGrantClientError({
             error: ERROR_PARSE,
             errno: ERRNO_PARSE,
             code: request.response.status,
             message: request.response.body,
           }));
+          return;
         }
 
         // "response.success" means status code is 200
         if (request.response.success) {
-          return resolve(body);
+          resolve(body);
+          return;
         }
 
         if (typeof body.errno === "number") {
           // Offset oauth server errnos to avoid conflict with other FxA server errnos
           body.errno += OAUTH_SERVER_ERRNO_OFFSET;
         } else if (body.errno) {
           body.errno = ERRNO_UNKNOWN_ERROR;
         }
-        return reject(new FxAccountsOAuthGrantClientError(body));
+        reject(new FxAccountsOAuthGrantClientError(body));
       };
 
       if (method === "POST") {
         request.post(params);
       } else {
         // method not supported
-        return reject(new FxAccountsOAuthGrantClientError({
+        reject(new FxAccountsOAuthGrantClientError({
           error: ERROR_NETWORK,
           errno: ERRNO_NETWORK,
           code: ERROR_CODE_METHOD_NOT_ALLOWED,
           message: ERROR_MSG_METHOD_NOT_ALLOWED,
         }));
       }
     });
   },
--- a/services/fxaccounts/FxAccountsProfileClient.jsm
+++ b/services/fxaccounts/FxAccountsProfileClient.jsm
@@ -141,58 +141,62 @@ this.FxAccountsProfileClient.prototype =
       request.setHeader("Authorization", "Bearer " + token);
       request.setHeader("Accept", "application/json");
       if (etag) {
         request.setHeader("If-None-Match", etag);
       }
 
       request.onComplete = function(error) {
         if (error) {
-          return reject(new FxAccountsProfileClientError({
+          reject(new FxAccountsProfileClientError({
             error: ERROR_NETWORK,
             errno: ERRNO_NETWORK,
             message: error.toString(),
           }));
+          return;
         }
 
         let body = null;
         try {
           if (request.response.status == 304) {
-            return resolve(null);
+            resolve(null);
+            return;
           }
           body = JSON.parse(request.response.body);
         } catch (e) {
-          return reject(new FxAccountsProfileClientError({
+          reject(new FxAccountsProfileClientError({
             error: ERROR_PARSE,
             errno: ERRNO_PARSE,
             code: request.response.status,
             message: request.response.body,
           }));
+          return;
         }
 
         // "response.success" means status code is 200
         if (request.response.success) {
-          return resolve({
+          resolve({
             body,
             etag: request.response.headers["etag"]
           });
+          return;
         }
-        return reject(new FxAccountsProfileClientError({
+        reject(new FxAccountsProfileClientError({
           error: body.error || ERROR_UNKNOWN,
           errno: body.errno || ERRNO_UNKNOWN_ERROR,
           code: request.response.status,
           message: body.message || body,
         }));
       };
 
       if (method === "GET") {
         request.get();
       } else {
         // method not supported
-        return reject(new FxAccountsProfileClientError({
+        reject(new FxAccountsProfileClientError({
           error: ERROR_NETWORK,
           errno: ERRNO_NETWORK,
           code: ERROR_CODE_METHOD_NOT_ALLOWED,
           message: ERROR_MSG_METHOD_NOT_ALLOWED,
         }));
       }
     });
   },
--- a/services/fxaccounts/FxAccountsPush.js
+++ b/services/fxaccounts/FxAccountsPush.js
@@ -79,16 +79,17 @@ FxAccountsPushService.prototype = {
     }
 
     // listen to new push messages, push changes and logout events
     Services.obs.addObserver(this, this.pushService.pushTopic, false);
     Services.obs.addObserver(this, this.pushService.subscriptionChangeTopic, false);
     Services.obs.addObserver(this, ONLOGOUT_NOTIFICATION, false);
 
     this.log.debug("FxAccountsPush initialized");
+    return true;
   },
   /**
    * Registers a new endpoint with the Push Server
    *
    * @returns {Promise}
    *          Promise always resolves with a subscription or a null if failed to subscribe.
    */
   registerPushEndpoint() {
@@ -117,27 +118,27 @@ FxAccountsPushService.prototype = {
    * @returns {Promise}
    */
   _observe(subject, topic, data) {
     this.log.trace(`observed topic=${topic}, data=${data}, subject=${subject}`);
     switch (topic) {
       case this.pushService.pushTopic:
         if (data === FXA_PUSH_SCOPE_ACCOUNT_UPDATE) {
           let message = subject.QueryInterface(Ci.nsIPushMessage);
-          return this._onPushMessage(message);
+          this._onPushMessage(message);
         }
         break;
       case this.pushService.subscriptionChangeTopic:
         if (data === FXA_PUSH_SCOPE_ACCOUNT_UPDATE) {
-          return this._onPushSubscriptionChange();
+          this._onPushSubscriptionChange();
         }
         break;
       case ONLOGOUT_NOTIFICATION:
         // user signed out, we need to stop polling the Push Server
-        return this.unsubscribe().catch(err => {
+        this.unsubscribe().catch(err => {
           this.log.error("Error during unsubscribe", err);
         });
       default:
         break;
     }
   },
   /**
    * Wrapper around _observe that catches errors
@@ -153,29 +154,32 @@ FxAccountsPushService.prototype = {
    * @private
    * @returns {Promise}
    */
   _onPushMessage(message) {
     this.log.trace("FxAccountsPushService _onPushMessage");
     if (!message.data) {
       // Use the empty signal to check the verification state of the account right away
       this.log.debug("empty push message - checking account status");
-      return this.fxAccounts.checkVerificationStatus();
+      this.fxAccounts.checkVerificationStatus();
+      return;
     }
     let payload = message.data.json();
     this.log.debug(`push command: ${payload.command}`);
     switch (payload.command) {
       case ON_DEVICE_CONNECTED_NOTIFICATION:
         Services.obs.notifyObservers(null, ON_DEVICE_CONNECTED_NOTIFICATION, payload.data.deviceName);
         break;
       case ON_DEVICE_DISCONNECTED_NOTIFICATION:
-        return this.fxAccounts.handleDeviceDisconnection(payload.data.id);
+        this.fxAccounts.handleDeviceDisconnection(payload.data.id);
+        return;
       case ON_PASSWORD_CHANGED_NOTIFICATION:
       case ON_PASSWORD_RESET_NOTIFICATION:
-        return this._onPasswordChanged();
+        this._onPasswordChanged();
+        return;
       case ON_COLLECTION_CHANGED_NOTIFICATION:
         Services.obs.notifyObservers(null, ON_COLLECTION_CHANGED_NOTIFICATION, payload.data.collections);
       default:
         this.log.warn("FxA Push command unrecognized: " + payload.command);
     }
   },
   /**
    * Check the FxA session status after a password change/reset event.
--- a/services/fxaccounts/FxAccountsStorage.jsm
+++ b/services/fxaccounts/FxAccountsStorage.jsm
@@ -301,22 +301,23 @@ this.FxAccountsStorageManager.prototype 
     return true;
   }),
 
   /* If we haven't managed to read the secure storage, try now, so
      we can merge our cached data with the data that's already been set.
   */
   _maybeReadAndUpdateSecure: Task.async(function* () {
     if (this.secureStorage == null || !this._needToReadSecure) {
-      return;
+      return null;
     }
     return this._queueStorageOperation(() => {
       if (this._needToReadSecure) { // we might have read it by now!
         return this._doReadAndUpdateSecure();
       }
+      return null;
     });
   }),
 
   /* Unconditionally read the secure storage and merge our cached data (ie, data
      which has already been set while the secure storage was locked) with
      the read data
   */
   _doReadAndUpdateSecure: Task.async(function* () {
--- a/services/fxaccounts/FxAccountsWebChannel.jsm
+++ b/services/fxaccounts/FxAccountsWebChannel.jsm
@@ -295,16 +295,17 @@ this.FxAccountsWebChannelHelpers.prototy
    */
   logout(uid) {
     return fxAccounts.getSignedInUser().then(userData => {
       if (userData.uid === uid) {
         // true argument is `localOnly`, because server-side stuff
         // has already been taken care of by the content server
         return fxAccounts.signOut(true);
       }
+      return null;
     });
   },
 
   changePassword(credentials) {
     // If |credentials| has fields that aren't handled by accounts storage,
     // updateUserAccountData will throw - mainly to prevent errors in code
     // that hard-codes field names.
     // However, in this case the field names aren't really in our control.
--- a/services/fxaccounts/tests/xpcshell/test_client.js
+++ b/services/fxaccounts/tests/xpcshell/test_client.js
@@ -651,22 +651,24 @@ add_task(function* test_registerDevice()
   const ERROR_NAME = "test that the client promise rejects";
 
   const server = httpd_setup({
     "/account/device": function(request, response) {
       const body = JSON.parse(CommonUtils.readBytesFromInputStream(request.bodyInputStream));
 
       if (body.id || !body.name || !body.type || Object.keys(body).length !== 2) {
         response.setStatusLine(request.httpVersion, 400, "Invalid request");
-        return response.bodyOutputStream.write("{}", 2);
+        response.bodyOutputStream.write("{}", 2);
+        return;
       }
 
       if (body.name === ERROR_NAME) {
         response.setStatusLine(request.httpVersion, 500, "Alas");
-        return response.bodyOutputStream.write("{}", 2);
+        response.bodyOutputStream.write("{}", 2);
+        return;
       }
 
       body.id = DEVICE_ID;
       body.createdAt = Date.now();
 
       const responseMessage = JSON.stringify(body);
 
       response.setStatusLine(request.httpVersion, 200, "OK");
@@ -701,22 +703,24 @@ add_task(function* test_updateDevice() {
   const ERROR_ID = "test that the client promise rejects";
 
   const server = httpd_setup({
     "/account/device": function(request, response) {
       const body = JSON.parse(CommonUtils.readBytesFromInputStream(request.bodyInputStream));
 
       if (!body.id || !body.name || body.type || Object.keys(body).length !== 2) {
         response.setStatusLine(request.httpVersion, 400, "Invalid request");
-        return response.bodyOutputStream.write("{}", 2);
+        response.bodyOutputStream.write("{}", 2);
+        return;
       }
 
       if (body.id === ERROR_ID) {
         response.setStatusLine(request.httpVersion, 500, "Alas");
-        return response.bodyOutputStream.write("{}", 2);
+        response.bodyOutputStream.write("{}", 2);
+        return;
       }
 
       const responseMessage = JSON.stringify(body);
 
       response.setStatusLine(request.httpVersion, 200, "OK");
       response.bodyOutputStream.write(responseMessage, responseMessage.length);
     },
   });
@@ -745,22 +749,24 @@ add_task(function* test_signOutAndDestro
   let emptyMessage = "{}";
 
   const server = httpd_setup({
     "/account/device/destroy": function(request, response) {
       const body = JSON.parse(CommonUtils.readBytesFromInputStream(request.bodyInputStream));
 
       if (!body.id) {
         response.setStatusLine(request.httpVersion, 400, "Invalid request");
-        return response.bodyOutputStream.write(emptyMessage, emptyMessage.length);
+        response.bodyOutputStream.write(emptyMessage, emptyMessage.length);
+        return;
       }
 
       if (body.id === ERROR_ID) {
         response.setStatusLine(request.httpVersion, 500, "Alas");
-        return response.bodyOutputStream.write("{}", 2);
+        response.bodyOutputStream.write("{}", 2);
+        return;
       }
 
       response.setStatusLine(request.httpVersion, 200, "OK");
       response.bodyOutputStream.write("{}", 2);
     },
   });
 
   const client = new FxAccountsClient(server.baseURI);
--- a/services/sync/modules-testing/rotaryengine.js
+++ b/services/sync/modules-testing/rotaryengine.js
@@ -115,10 +115,11 @@ RotaryEngine.prototype = {
       return "DUPE_LOCAL";
     }
 
     for (let [id, value] of Object.entries(this._store.items)) {
       if (item.denomination == value) {
         return id;
       }
     }
+    return null;
   }
 };
--- a/services/sync/modules/browserid_identity.js
+++ b/services/sync/modules/browserid_identity.js
@@ -522,17 +522,17 @@ this.BrowserIDManager.prototype = {
       log.info("Unable to fetch keys (master-password locked?), so aborting token fetch");
       return Promise.resolve(null);
     }
 
     let maybeFetchKeys = () => {
       // This is called at login time and every time we need a new token - in
       // the latter case we already have kA and kB, so optimise that case.
       if (userData.kA && userData.kB) {
-        return;
+        return null;
       }
       log.info("Fetching new keys");
       return this._fxaService.getKeys().then(
         newUserData => {
           userData = newUserData;
           this._updateSignedInUser(userData); // throws if the user changed.
         }
       );
--- a/services/sync/modules/engines.js
+++ b/services/sync/modules/engines.js
@@ -582,17 +582,18 @@ EngineManager.prototype = {
    * objects to register.
    *
    * @param engineObject
    *        Engine object used to get an instance of the engine
    * @return The engine object if anything failed
    */
   register(engineObject) {
     if (Array.isArray(engineObject)) {
-      return engineObject.map(this.register, this);
+      engineObject.map(this.register, this);
+      return;
     }
 
     try {
       let engine = new engineObject(this.service);
       let name = engine.name;
       if (name in this._engines) {
         this._log.error("Engine '" + name + "' is already registered!");
       } else {
--- a/services/sync/modules/engines/bookmarks.js
+++ b/services/sync/modules/engines/bookmarks.js
@@ -377,17 +377,17 @@ BookmarksEngine.prototype = {
       case "folder":
       case "livemark":
         key = "f" + (item.title || "");
         break;
       case "separator":
         key = "s" + item.pos;
         break;
       default:
-        return;
+        return undefined;
     }
 
     // Figure out if we have a map to use!
     // This will throw in some circumstances. That's fine.
     let guidMap = this._guidMap;
 
     // Give the GUID if we have the matching pair.
     let parentName = item.parentName || "";
@@ -535,17 +535,17 @@ BookmarksEngine.prototype = {
 
   _findDupe: function _findDupe(item) {
     this._log.trace("Finding dupe for " + item.id +
                     " (already duped: " + item.hasDupe + ").");
 
     // Don't bother finding a dupe if the incoming item has duplicates.
     if (item.hasDupe) {
       this._log.trace(item.id + " already a dupe: not finding one.");
-      return;
+      return null;
     }
     let mapped = this._mapDupe(item);
     this._log.debug(item.id + " mapped to " + mapped);
     // We must return a string, not an object, and the entries in the GUIDMap
     // are created via "new String()" making them an object.
     return mapped ? mapped.toString() : mapped;
   },
 
--- a/services/sync/modules/engines/forms.js
+++ b/services/sync/modules/engines/forms.js
@@ -63,17 +63,17 @@ var FormWrapper = {
     }
     let cb = Async.makeSpinningCallback();
     let callbacks = {
       handleCompletion(reason) {
         cb();
       }
     };
     Svc.FormHistory.update(changes, callbacks);
-    return cb.wait();
+    cb.wait();
   },
 
   getEntry(guid) {
     let results = this._searchSpinningly(this._getEntryCols, {guid});
     if (!results.length) {
       return null;
     }
     return {name: results[0].fieldname, value: results[0].value};
--- a/services/sync/modules/record.js
+++ b/services/sync/modules/record.js
@@ -987,33 +987,36 @@ PostQueue.prototype = {
     this.queued = "";
     this.numQueued = 0;
     let response = this.poster(queued, headers, batch, !!(finalBatchPost && this.batchID !== null));
 
     if (!response.success) {
       this.log.trace("Server error response during a batch", response);
       // not clear what we should do here - we expect the consumer of this to
       // abort by throwing in the postCallback below.
-      return this.postCallback(response, !finalBatchPost);
+      this.postCallback(response, !finalBatchPost);
+      return;
     }
 
     if (finalBatchPost) {
       this.log.trace("Committed batch", this.batchID);
       this.batchID = undefined; // we are now in "first post for the batch" state.
       this.lastModified = response.headers["x-last-modified"];
-      return this.postCallback(response, false);
+      this.postCallback(response, false);
+      return;
     }
 
     if (response.status != 202) {
       if (this.batchID) {
         throw new Error("Server responded non-202 success code while a batch was in progress");
       }
       this.batchID = null; // no batch semantics are in place.
       this.lastModified = response.headers["x-last-modified"];
-      return this.postCallback(response, false);
+      this.postCallback(response, false);
+      return;
     }
 
     // this response is saying the server has batch semantics - we should
     // always have a batch ID in the response.
     let responseBatchID = response.obj.batch;
     this.log.trace("Server responsed 202 with batch", responseBatchID);
     if (!responseBatchID) {
       this.log.error("Invalid server response: 202 without a batch ID", response);
--- a/services/sync/modules/service.js
+++ b/services/sync/modules/service.js
@@ -1084,17 +1084,17 @@ Sync11Service.prototype = {
         this._log.debug("In sync: should login.");
         if (!this.login()) {
           this._log.debug("Not syncing: login returned false.");
           return;
         }
       } else {
         this._log.trace("In sync: no need to login.");
       }
-      return this._lockedSync(engineNamesToSync);
+      this._lockedSync(engineNamesToSync);
     })();
   },
 
   /**
    * Sync up engines with the server.
    */
   _lockedSync: function _lockedSync(engineNamesToSync) {
     return this._lock("service.js: sync",
--- a/services/sync/tests/unit/test_addon_utils.js
+++ b/services/sync/tests/unit/test_addon_utils.js
@@ -32,16 +32,17 @@ function createAndStartHTTPServer(port =
     server.start(port);
 
     return server;
   } catch (ex) {
     _("Got exception starting HTTP server on port " + port);
     _("Error: " + Log.exceptionStr(ex));
     do_throw(ex);
   }
+  return null; /* not hit, but keeps eslint happy! */
 }
 
 function run_test() {
   initTestLogging("Trace");
 
   run_next_test();
 }
 
--- a/services/sync/tests/unit/test_addons_store.js
+++ b/services/sync/tests/unit/test_addons_store.js
@@ -84,16 +84,17 @@ function createAndStartHTTPServer(port) 
     server.start(port);
 
     return server;
   } catch (ex) {
     _("Got exception starting HTTP server on port " + port);
     _("Error: " + Log.exceptionStr(ex));
     do_throw(ex);
   }
+  return null; /* not hit, but keeps eslint happy! */
 }
 
 function run_test() {
   initTestLogging("Trace");
   Log.repository.getLogger("Sync.Engine.Addons").level = Log.Level.Trace;
   Log.repository.getLogger("Sync.Tracker.Addons").level = Log.Level.Trace;
   Log.repository.getLogger("Sync.AddonsRepository").level =
     Log.Level.Trace;
--- a/services/sync/tests/unit/test_fxa_node_reassignment.js
+++ b/services/sync/tests/unit/test_fxa_node_reassignment.js
@@ -99,22 +99,22 @@ function prepareServer(cbAfterTokenFetch
     return server;
   });
 }
 
 function getReassigned() {
   try {
     return Services.prefs.getBoolPref("services.sync.lastSyncReassigned");
   } catch (ex) {
-    if (ex.result == Cr.NS_ERROR_UNEXPECTED) {
-      return false;
+    if (ex.result != Cr.NS_ERROR_UNEXPECTED) {
+      do_throw("Got exception retrieving lastSyncReassigned: " +
+               Log.exceptionStr(ex));
     }
-    do_throw("Got exception retrieving lastSyncReassigned: " +
-             Log.exceptionStr(ex));
   }
+  return false;
 }
 
 /**
  * Make a test request to `url`, then watch the result of two syncs
  * to ensure that a node request was made.
  * Runs `between` between the two. This can be used to undo deliberate failure
  * setup, detach observers, etc.
  */
--- a/services/sync/tests/unit/test_hmac_error.js
+++ b/services/sync/tests/unit/test_hmac_error.js
@@ -153,17 +153,17 @@ add_task(async function hmac_error_durin
   should401 = true;
 
   // Use observers to perform actions when our sync finishes.
   // This allows us to observe the automatic next-tick sync that occurs after
   // an abort.
   function onSyncError() {
     do_throw("Should not get a sync error!");
   }
-  function onSyncFinished() {}
+  let onSyncFinished = function() {}
   let obs = {
     observe: function observe(subject, topic, data) {
       switch (topic) {
         case "weave:service:sync:error":
           onSyncError();
           break;
         case "weave:service:sync:finish":
           onSyncFinished();
--- a/services/sync/tests/unit/test_node_reassignment.js
+++ b/services/sync/tests/unit/test_node_reassignment.js
@@ -65,22 +65,22 @@ async function prepareServer() {
   await configureIdentity({username: "johndoe"}, server);
   return server;
 }
 
 function getReassigned() {
   try {
     return Services.prefs.getBoolPref("services.sync.lastSyncReassigned");
   } catch (ex) {
-    if (ex.result == Cr.NS_ERROR_UNEXPECTED) {
-      return false;
+    if (ex.result != Cr.NS_ERROR_UNEXPECTED) {
+      do_throw("Got exception retrieving lastSyncReassigned: " +
+               Log.exceptionStr(ex));
     }
-    do_throw("Got exception retrieving lastSyncReassigned: " +
-             Log.exceptionStr(ex));
   }
+  return false;
 }
 
 /**
  * Make a test request to `url`, then watch the result of two syncs
  * to ensure that a node request was made.
  * Runs `between` between the two. This can be used to undo deliberate failure
  * setup, detach observers, etc.
  */
--- a/services/sync/tests/unit/test_password_store.js
+++ b/services/sync/tests/unit/test_password_store.js
@@ -35,16 +35,17 @@ function checkRecord(name, record, expec
       } else {
         do_check_eq(stored_record.timePasswordChanged, expectedTimePasswordChanged);
       }
       return stored_record.timePasswordChanged;
     }
   } else {
     do_check_true(!store.getAllIDs()[record.id]);
   }
+  return undefined;
 }
 
 
 function changePassword(name, hostname, password, expectedCount, timeCreated,
                         expectedTimeCreated, timePasswordChanged,
                         expectedTimePasswordChanged, insert, recordIsUpdated) {
 
   const BOGUS_GUID = "zzzzzz" + hostname;
--- a/services/sync/tps/extensions/tps/resource/modules/forms.jsm
+++ b/services/sync/tps/extensions/tps/resource/modules/forms.jsm
@@ -167,16 +167,17 @@ FormData.prototype = {
         // this item doesn't exist yet in the db, so we need to insert it
         return FormDB.insertValue(this.fieldname, this.value,
                                   this.hours_to_us(this.date));
       }
       /* Right now, we ignore this case.  If bug 552531 is ever fixed,
          we might need to add code here to update the firstUsed or
          lastUsed fields, as appropriate.
        */
+      return null;
     });
   },
 
   /**
    * Find
    *
    * Attempts to locate an entry in the moz_formhistory database that
    * matches the fieldname and value for this FormData object.