Bug 1056918 - Allow distinguishing between 'not found' and 'database error' programmatically r=standard8
authorAdam Roach [:abr] <adam@nostrum.com>
Tue, 26 Aug 2014 09:56:42 -0500
changeset 201582 2b5bc470740d596527596a57943a1f424c5df5d2
parent 201581 ce6cce273a0aa21dcff49c1f234b5ad1d7502b42
child 201583 5efbfff98372042e9575ce02312627f458fcad36
push id27374
push userryanvm@gmail.com
push dateTue, 26 Aug 2014 18:16:27 +0000
treeherdermozilla-central@c850f3af9f2c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersstandard8
bugs1056918
milestone34.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 1056918 - Allow distinguishing between 'not found' and 'database error' programmatically r=standard8
browser/components/loop/LoopContacts.jsm
browser/components/loop/test/mochitest/browser_LoopContacts.js
--- a/browser/components/loop/LoopContacts.jsm
+++ b/browser/components/loop/LoopContacts.jsm
@@ -484,16 +484,19 @@ let LoopContactsInternal = Object.freeze
   /**
    * Retrieve a specific contact from the data store.
    *
    * @param {String}   guid     String identifier of the contact to retrieve
    * @param {Function} callback Function that will be invoked once the operation
    *                            finished. The first argument passed will be an
    *                            `Error` object or `null`. The second argument will
    *                            be the contact object, if successful.
+   *                            If no object matching guid could be found,
+   *                            then the callback is called with both arguments
+   *                            set to `null`.
    */
   get: function(guid, callback) {
     LoopStorage.getStore(kObjectStoreName, (err, store) => {
       if (err) {
         callback(err);
         return;
       }
 
@@ -502,18 +505,17 @@ let LoopContactsInternal = Object.freeze
         request = store.get(guid);
       } catch (ex) {
         callback(ex);
         return;
       }
 
       request.onsuccess = event => {
         if (!event.target.result) {
-          callback(new Error("Contact with " + kKeyPath + " '" +
-                             guid + "' could not be found"));;
+          callback(null, null);
           return;
         }
         let contact = extend({}, event.target.result);
         contact[kKeyPath] = guid;
         callback(null, contact);
       };
       request.onerror = event => callback(event.target.error);
     });
@@ -523,16 +525,19 @@ let LoopContactsInternal = Object.freeze
    * Retrieve a specific contact from the data store using the kServiceIdIndex
    * property.
    *
    * @param {String}   serviceId String identifier of the contact to retrieve
    * @param {Function} callback  Function that will be invoked once the operation
    *                             finished. The first argument passed will be an
    *                             `Error` object or `null`. The second argument will
    *                             be the contact object, if successfull.
+   *                             If no object matching serviceId could be found,
+   *                             then the callback is called with both arguments
+   *                             set to `null`.
    */
   getByServiceId: function(serviceId, callback) {
     LoopStorage.getStore(kObjectStoreName, (err, store) => {
       if (err) {
         callback(err);
         return;
       }
 
@@ -542,18 +547,17 @@ let LoopContactsInternal = Object.freeze
         request = index.get(serviceId);
       } catch (ex) {
         callback(ex);
         return;
       }
 
       request.onsuccess = event => {
         if (!event.target.result) {
-          callback(new Error("Contact with " + kServiceIdIndex + " '" +
-                             serviceId + "' could not be found"));
+          callback(null, null);
           return;
         }
 
         let contact = extend({}, event.target.result);
         callback(null, contact);
       };
       request.onerror = event => callback(event.target.error);
     });
@@ -653,16 +657,21 @@ let LoopContactsInternal = Object.freeze
     let guid = details[kKeyPath];
 
     this.get(guid, (err, contact) => {
       if (err) {
         callback(err);
         return;
       }
 
+      if (!contact) {
+        callback(new Error("Contact with " + kKeyPath + " '" +
+                           guid + "' could not be found"));
+      }
+
       LoopStorage.getStore(kObjectStoreName, (err, store) => {
         if (err) {
           callback(err);
           return;
         }
 
         let previous = extend({}, contact);
         // Update the contact with properties provided by `details`.
@@ -697,16 +706,21 @@ let LoopContactsInternal = Object.freeze
    */
   block: function(guid, callback) {
     this.get(guid, (err, contact) => {
       if (err) {
         callback(err);
         return;
       }
 
+      if (!contact) {
+        callback(new Error("Contact with " + kKeyPath + " '" +
+                           guid + "' could not be found"));
+      }
+
       contact.blocked = true;
       this.update(contact, callback);
     });
   },
 
   /**
    * Un-block a specific contact in the data store.
    *
@@ -718,16 +732,21 @@ let LoopContactsInternal = Object.freeze
    */
   unblock: function(guid, callback) {
     this.get(guid, (err, contact) => {
       if (err) {
         callback(err);
         return;
       }
 
+      if (!contact) {
+        callback(new Error("Contact with " + kKeyPath + " '" +
+                           guid + "' could not be found"));
+      }
+
       contact.blocked = false;
       this.update(contact, callback);
     });
   },
 
   /**
    * Import a list of (new) contacts from an external data source.
    *
--- a/browser/components/loop/test/mochitest/browser_LoopContacts.js
+++ b/browser/components/loop/test/mochitest/browser_LoopContacts.js
@@ -225,51 +225,48 @@ add_task(function* () {
       compareContacts(contacts[i], kContacts[i]);
     }
     deferred.resolve();
   });
   yield deferred.promise;
 
   // Get a non-existent contact.
   deferred = Promise.defer();
-  LoopContacts.get(1000, err => {
-    Assert.ok(err, "There should be an error");
-    Assert.equal(err.message, "Contact with _guid '1000' could not be found",
-                 "Error message should be correct");
+  LoopContacts.get(1000, (err, contact) => {
+    Assert.ok(!err, "There shouldn't be an error");
+    Assert.ok(!contact, "There shouldn't be a contact");
     deferred.resolve();
   });
   yield deferred.promise;
 });
 
 // Test removing a contact.
 add_task(function* () {
   let contacts = yield promiseLoadContacts();
 
   // Remove a single contact.
   let deferred = Promise.defer();
   let toRemove = contacts[2]._guid;
   gExpectedRemovals.push(toRemove);
   LoopContacts.remove(toRemove, err => {
     Assert.ok(!err, "There shouldn't be an error");
 
-    LoopContacts.get(toRemove, err => {
-      Assert.ok(err, "There should be an error");
-      Assert.equal(err.message, "Contact with _guid '" + toRemove + "' could not be found",
-                   "Error message should be correct");
+    LoopContacts.get(toRemove, (err, contact) => {
+      Assert.ok(!err, "There shouldn't be an error");
+      Assert.ok(!contact, "There shouldn't be a contact");
       deferred.resolve();
     });
   });
   yield deferred.promise;
 
   // Remove a non-existing contact.
   deferred = Promise.defer();
-  LoopContacts.remove(1000, err => {
-    Assert.ok(err, "There should be an error");
-    Assert.equal(err.message, "Contact with _guid '1000' could not be found",
-                 "Error message should be correct");
+  LoopContacts.remove(1000, (err, contact) => {
+    Assert.ok(!err, "There shouldn't be an error");
+    Assert.ok(!contact, "There shouldn't be a contact");
     deferred.resolve();
   });
   yield deferred.promise;
 
   // Remove multiple contacts.
   deferred = Promise.defer();
   toRemove = [contacts[0]._guid, contacts[1]._guid];
   gExpectedRemovals.push(...toRemove);
@@ -318,17 +315,17 @@ add_task(function* () {
   yield deferred.promise;
 
   // Update a non-existing contact.
   deferred = Promise.defer();
   toUpdate = {
     _guid: 1000,
     bday: newBday
   };
-  LoopContacts.update(toUpdate, err => {
+  LoopContacts.update(toUpdate, (err, contact) => {
     Assert.ok(err, "There should be an error");
     Assert.equal(err.message, "Contact with _guid '1000' could not be found",
                  "Error message should be correct");
     deferred.resolve();
   });
   yield deferred.promise;
 });