Bug 969318 - Mute "A promise chain failed to handle a rejection" error from the livemarks service. r=mano
authorMarco Bonardo <mbonardo@mozilla.com>
Wed, 12 Mar 2014 16:24:23 +0100
changeset 173276 60c1af78091ab904718d3c69d7e4797190a3c134
parent 173275 7fb98742da4a5c7d02c7bf96438dddb377b07392
child 173277 56ac183ad1e21219994a080f3f65454b945b9bb0
push id26398
push userkwierso@gmail.com
push dateThu, 13 Mar 2014 03:01:55 +0000
treeherdermozilla-central@46041cc216fd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmano
bugs969318
milestone30.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 969318 - Mute "A promise chain failed to handle a rejection" error from the livemarks service. r=mano
browser/components/distribution.js
browser/components/places/content/bookmarkProperties.js
browser/components/places/content/browserPlacesViews.js
browser/components/places/content/controller.js
browser/components/places/content/editBookmarkOverlay.js
browser/components/places/content/treeView.js
services/sync/modules/engines/bookmarks.js
services/sync/tps/extensions/tps/modules/bookmarks.jsm
toolkit/components/places/BookmarkHTMLUtils.jsm
toolkit/components/places/BookmarkJSONUtils.jsm
toolkit/components/places/PlacesUtils.jsm
toolkit/components/places/mozIAsyncLivemarks.idl
toolkit/components/places/nsLivemarkService.js
toolkit/components/places/tests/chrome/test_303567.xul
toolkit/components/places/tests/chrome/test_341972a.xul
toolkit/components/places/tests/chrome/test_341972b.xul
toolkit/components/places/tests/chrome/test_342484.xul
toolkit/components/places/tests/chrome/test_381357.xul
toolkit/components/places/tests/chrome/test_reloadLivemarks.xul
toolkit/components/places/tests/queries/head_queries.js
toolkit/components/places/tests/unit/test_384370.js
toolkit/components/places/tests/unit/test_bookmarks_html.js
toolkit/components/places/tests/unit/test_bookmarks_html_corrupt.js
toolkit/components/places/tests/unit/test_bookmarks_json.js
toolkit/components/places/tests/unit/test_bug636917_isLivemark.js
toolkit/components/places/tests/unit/test_mozIAsyncLivemarks.js
--- a/browser/components/distribution.js
+++ b/browser/components/distribution.js
@@ -162,17 +162,17 @@ DistributionCustomizer.prototype = {
           index = prependIndex++;
 
         // Don't bother updating the livemark contents on creation.
         PlacesUtils.livemarks.addLivemark({ title: items[iid]["title"]
                                           , parentId: parentId
                                           , index: index
                                           , feedURI: this._makeURI(items[iid]["feedLink"])
                                           , siteURI: this._makeURI(items[iid]["siteLink"])
-                                          });
+                                          }).then(null, Cu.reportError);
         break;
 
       case "bookmark":
       default:
         if (iid < defaultItemId)
           index = prependIndex++;
 
         newId = PlacesUtils.bookmarks.insertBookmark(parentId,
--- a/browser/components/places/content/bookmarkProperties.js
+++ b/browser/components/places/content/bookmarkProperties.js
@@ -246,34 +246,30 @@ var BookmarkPropertiesPanel = {
           // Load In Sidebar
           this._loadInSidebar = PlacesUtils.annotations
                                            .itemHasAnnotation(this._itemId,
                                                               PlacesUIUtils.LOAD_IN_SIDEBAR_ANNO);
           break;
 
         case "folder":
           this._itemType = BOOKMARK_FOLDER;
-          PlacesUtils.livemarks.getLivemark(
-            { id: this._itemId },
-            (function (aStatus, aLivemark) {
-              if (Components.isSuccessCode(aStatus)) {
-                this._itemType = LIVEMARK_CONTAINER;
-                this._feedURI = aLivemark.feedURI;
-                this._siteURI = aLivemark.siteURI;
-                this._fillEditProperties();
+          PlacesUtils.livemarks.getLivemark({ id: this._itemId })
+            .then(aLivemark => {
+              this._itemType = LIVEMARK_CONTAINER;
+              this._feedURI = aLivemark.feedURI;
+              this._siteURI = aLivemark.siteURI;
+              this._fillEditProperties();
 
-                let acceptButton = document.documentElement.getButton("accept");
-                acceptButton.disabled = !this._inputIsValid();
+              let acceptButton = document.documentElement.getButton("accept");
+              acceptButton.disabled = !this._inputIsValid();
 
-                let newHeight = window.outerHeight +
-                                this._element("descriptionField").boxObject.height;
-                window.resizeTo(window.outerWidth, newHeight);
-              }
-            }).bind(this)
-          );
+              let newHeight = window.outerHeight +
+                              this._element("descriptionField").boxObject.height;
+              window.resizeTo(window.outerWidth, newHeight);
+            }, () => undefined);
 
           break;
       }
 
       // Description
       if (PlacesUtils.annotations
                      .itemHasAnnotation(this._itemId, PlacesUIUtils.DESCRIPTION_ANNO)) {
         this._description = PlacesUtils.annotations
--- a/browser/components/places/content/browserPlacesViews.js
+++ b/browser/components/places/content/browserPlacesViews.js
@@ -312,31 +312,27 @@ PlacesViewBase.prototype = {
           if (PlacesUtils.nodeIsTagQuery(aPlacesNode))
             element.setAttribute("tagContainer", "true");
           else if (PlacesUtils.nodeIsDay(aPlacesNode))
             element.setAttribute("dayContainer", "true");
           else if (PlacesUtils.nodeIsHost(aPlacesNode))
             element.setAttribute("hostContainer", "true");
         }
         else if (itemId != -1) {
-          PlacesUtils.livemarks.getLivemark(
-            { id: itemId },
-            function (aStatus, aLivemark) {
-              if (Components.isSuccessCode(aStatus)) {
-                element.setAttribute("livemark", "true");
+          PlacesUtils.livemarks.getLivemark({ id: itemId })
+            .then(aLivemark => {
+              element.setAttribute("livemark", "true");
 #ifdef XP_MACOSX
-                // OS X native menubar doesn't track list-style-images since
-                // it doesn't have a frame (bug 733415).  Thus enforce updating.
-                element.setAttribute("image", "");
-                element.removeAttribute("image");
+              // OS X native menubar doesn't track list-style-images since
+              // it doesn't have a frame (bug 733415).  Thus enforce updating.
+              element.setAttribute("image", "");
+              element.removeAttribute("image");
 #endif
-                this.controller.cacheLivemarkInfo(aPlacesNode, aLivemark);
-              }
-            }.bind(this)
-          );
+              this.controller.cacheLivemarkInfo(aPlacesNode, aLivemark);
+            }, () => undefined);
         }
 
         let popup = document.createElement("menupopup");
         popup._placesNode = PlacesUtils.asContainer(aPlacesNode);
 
         if (!this._nativeView) {
           popup.setAttribute("placespopup", "true");
         }
@@ -504,26 +500,22 @@ PlacesViewBase.prototype = {
 #ifdef XP_MACOSX
         // OS X native menubar doesn't track list-style-images since
         // it doesn't have a frame (bug 733415).  Thus enforce updating.
         menu.setAttribute("image", "");
         menu.removeAttribute("image");
 #endif
       }
 
-      PlacesUtils.livemarks.getLivemark(
-        { id: aPlacesNode.itemId },
-        function (aStatus, aLivemark) {
-          if (Components.isSuccessCode(aStatus)) {
-            // Controller will use this to build the meta data for the node.
-            this.controller.cacheLivemarkInfo(aPlacesNode, aLivemark);
-            this.invalidateContainer(aPlacesNode);
-          }
-        }.bind(this)
-      );
+      PlacesUtils.livemarks.getLivemark({ id: aPlacesNode.itemId })
+        .then(aLivemark => {
+          // Controller will use this to build the meta data for the node.
+          this.controller.cacheLivemarkInfo(aPlacesNode, aLivemark);
+          this.invalidateContainer(aPlacesNode);
+        }, () => undefined);
     }
   },
 
   nodeTitleChanged:
   function PVB_nodeTitleChanged(aPlacesNode, aNewTitle) {
     let elt = this._getDOMNodeForPlacesNode(aPlacesNode);
 
     // There's no UI representation for the root node, thus there's
@@ -642,69 +634,65 @@ PlacesViewBase.prototype = {
       this.invalidateContainer(aPlacesNode);
 
       if (PlacesUtils.nodeIsFolder(aPlacesNode)) {
         let queryOptions = PlacesUtils.asQuery(this._result.root).queryOptions;
         if (queryOptions.excludeItems) {
           return;
         }
 
-        PlacesUtils.livemarks.getLivemark({ id: aPlacesNode.itemId },
-          function (aStatus, aLivemark) {
-            if (Components.isSuccessCode(aStatus)) {
-              let shouldInvalidate =
-                !this.controller.hasCachedLivemarkInfo(aPlacesNode);
-              this.controller.cacheLivemarkInfo(aPlacesNode, aLivemark);
-              if (aNewState == Ci.nsINavHistoryContainerResultNode.STATE_OPENED) {
-                aLivemark.registerForUpdates(aPlacesNode, this);
-                // Prioritize the current livemark.
-                aLivemark.reload();
-                PlacesUtils.livemarks.reloadLivemarks();
-                if (shouldInvalidate)
-                  this.invalidateContainer(aPlacesNode);
-              }
-              else {
-                aLivemark.unregisterForUpdates(aPlacesNode);
-              }
+        PlacesUtils.livemarks.getLivemark({ id: aPlacesNode.itemId })
+          .then(aLivemark => {
+            let shouldInvalidate =
+              !this.controller.hasCachedLivemarkInfo(aPlacesNode);
+            this.controller.cacheLivemarkInfo(aPlacesNode, aLivemark);
+            if (aNewState == Ci.nsINavHistoryContainerResultNode.STATE_OPENED) {
+              aLivemark.registerForUpdates(aPlacesNode, this);
+              // Prioritize the current livemark.
+              aLivemark.reload();
+              PlacesUtils.livemarks.reloadLivemarks();
+              if (shouldInvalidate)
+                this.invalidateContainer(aPlacesNode);
             }
-          }.bind(this)
-        );
+            else {
+              aLivemark.unregisterForUpdates(aPlacesNode);
+            }
+          }, () => undefined);
       }
     }
   },
 
   _populateLivemarkPopup: function PVB__populateLivemarkPopup(aPopup)
   {
     this._setLivemarkSiteURIMenuItem(aPopup);
     // Show the loading status only if there are no entries yet.
     if (aPopup._startMarker.nextSibling == aPopup._endMarker)
       this._setLivemarkStatusMenuItem(aPopup, Ci.mozILivemark.STATUS_LOADING);
 
-    PlacesUtils.livemarks.getLivemark({ id: aPopup._placesNode.itemId },
-      function (aStatus, aLivemark) {
+    PlacesUtils.livemarks.getLivemark({ id: aPopup._placesNode.itemId })
+      .then(aLivemark => {
         let placesNode = aPopup._placesNode;
-        if (!Components.isSuccessCode(aStatus) || !placesNode.containerOpen)
+        if (!placesNode.containerOpen)
           return;
 
         if (aLivemark.status != Ci.mozILivemark.STATUS_LOADING)
           this._setLivemarkStatusMenuItem(aPopup, aLivemark.status);
         this._cleanPopup(aPopup,
           this._nativeView && aPopup.parentNode.hasAttribute("open"));
 
         let children = aLivemark.getNodesForContainer(placesNode);
         for (let i = 0; i < children.length; i++) {
           let child = children[i];
           this.nodeInserted(placesNode, child, i);
           if (child.accessCount)
             this._getDOMNodeForPlacesNode(child).setAttribute("visited", true);
           else
             this._getDOMNodeForPlacesNode(child).removeAttribute("visited");
         }
-      }.bind(this)
-    );
+      }, Components.utils.reportError);
   },
 
   invalidateContainer: function PVB_invalidateContainer(aPlacesNode) {
     let elt = this._getDOMNodeForPlacesNode(aPlacesNode);
     elt._built = false;
 
     // If the menupopup is open we should live-update it.
     if (elt.parentNode.open)
@@ -1003,25 +991,21 @@ PlacesToolbar.prototype = {
         button.setAttribute("container", "true");
 
         if (PlacesUtils.nodeIsQuery(aChild)) {
           button.setAttribute("query", "true");
           if (PlacesUtils.nodeIsTagQuery(aChild))
             button.setAttribute("tagContainer", "true");
         }
         else if (PlacesUtils.nodeIsFolder(aChild)) {
-          PlacesUtils.livemarks.getLivemark(
-            { id: aChild.itemId },
-            function (aStatus, aLivemark) {
-              if (Components.isSuccessCode(aStatus)) {
-                button.setAttribute("livemark", "true");
-                this.controller.cacheLivemarkInfo(aChild, aLivemark);
-              }
-            }.bind(this)
-          );
+          PlacesUtils.livemarks.getLivemark({ id: aChild.itemId })
+            .then(aLivemark => {
+              button.setAttribute("livemark", "true");
+              this.controller.cacheLivemarkInfo(aChild, aLivemark);
+            }, () => undefined);
         }
 
         let popup = document.createElement("menupopup");
         popup.setAttribute("placespopup", "true");
         button.appendChild(popup);
         popup._placesNode = PlacesUtils.asContainer(aChild);
         popup.setAttribute("context", "placesContext");
 
@@ -1263,25 +1247,21 @@ PlacesToolbar.prototype = {
 
     if (elt.parentNode == this._rootElt) {
       // Node is on the toolbar.
 
       // All livemarks have a feedURI, so use it as our indicator.
       if (aAnno == PlacesUtils.LMANNO_FEEDURI) {
         elt.setAttribute("livemark", true);
 
-        PlacesUtils.livemarks.getLivemark(
-          { id: aPlacesNode.itemId },
-          function (aStatus, aLivemark) {
-            if (Components.isSuccessCode(aStatus)) {
-              this.controller.cacheLivemarkInfo(aPlacesNode, aLivemark);
-              this.invalidateContainer(aPlacesNode);
-            }
-          }.bind(this)
-        );
+        PlacesUtils.livemarks.getLivemark({ id: aPlacesNode.itemId })
+          .then(aLivemark => {
+            this.controller.cacheLivemarkInfo(aPlacesNode, aLivemark);
+            this.invalidateContainer(aPlacesNode);
+          }, Components.utils.reportError);
       }
     }
     else {
       // Node is in a submenu.
       PlacesViewBase.prototype.nodeAnnotationChanged.apply(this, arguments);
     }
   },
 
@@ -1835,25 +1815,21 @@ PlacesPanelMenuView.prototype = {
         button.setAttribute("container", "true");
 
         if (PlacesUtils.nodeIsQuery(aChild)) {
           button.setAttribute("query", "true");
           if (PlacesUtils.nodeIsTagQuery(aChild))
             button.setAttribute("tagContainer", "true");
         }
         else if (PlacesUtils.nodeIsFolder(aChild)) {
-          PlacesUtils.livemarks.getLivemark(
-            { id: aChild.itemId },
-            function (aStatus, aLivemark) {
-              if (Components.isSuccessCode(aStatus)) {
-                button.setAttribute("livemark", "true");
-                this.controller.cacheLivemarkInfo(aChild, aLivemark);
-              }
-            }.bind(this)
-          );
+          PlacesUtils.livemarks.getLivemark({ id: aChild.itemId })
+            .then(aLivemark => {
+              button.setAttribute("livemark", "true");
+              this.controller.cacheLivemarkInfo(aChild, aLivemark);
+            }, () => undefined);
         }
       }
       else if (PlacesUtils.nodeIsURI(aChild)) {
         button.setAttribute("scheme",
                             PlacesUIUtils.guessUrlSchemeForUI(aChild.uri));
       }
     }
 
@@ -1907,25 +1883,21 @@ PlacesPanelMenuView.prototype = {
 
     if (elt.parentNode != this._rootElt)
       return;
 
     // All livemarks have a feedURI, so use it as our indicator.
     if (aAnno == PlacesUtils.LMANNO_FEEDURI) {
       elt.setAttribute("livemark", true);
 
-      PlacesUtils.livemarks.getLivemark(
-        { id: aPlacesNode.itemId },
-        function (aStatus, aLivemark) {
-          if (Components.isSuccessCode(aStatus)) {
-            this.controller.cacheLivemarkInfo(aPlacesNode, aLivemark);
-            this.invalidateContainer(aPlacesNode);
-          }
-        }.bind(this)
-      );
+      PlacesUtils.livemarks.getLivemark({ id: aPlacesNode.itemId })
+        .then(aLivemark => {
+          this.controller.cacheLivemarkInfo(aPlacesNode, aLivemark);
+          this.invalidateContainer(aPlacesNode);
+        }, Components.utils.reportError);
     }
   },
 
   nodeTitleChanged: function PAMV_nodeTitleChanged(aPlacesNode, aNewTitle) {
     let elt = this._getDOMNodeForPlacesNode(aPlacesNode);
 
     // There's no UI representation for the root node.
     if (elt == this._rootElt)
--- a/browser/components/places/content/controller.js
+++ b/browser/components/places/content/controller.js
@@ -689,24 +689,20 @@ PlacesController.prototype = {
 
   /**
    * Reloads the selected livemark if any.
    */
   reloadSelectedLivemark: function PC_reloadSelectedLivemark() {
     var selectedNode = this._view.selectedNode;
     if (selectedNode) {
       let itemId = selectedNode.itemId;
-      PlacesUtils.livemarks.getLivemark(
-        { id: itemId },
-        (function(aStatus, aLivemark) {
-          if (Components.isSuccessCode(aStatus)) {
-            aLivemark.reload(true);
-          }
-        }).bind(this)
-      );
+      PlacesUtils.livemarks.getLivemark({ id: itemId })
+        .then(aLivemark => {
+          aLivemark.reload(true);
+        }, Components.utils.reportError);
     }
   },
 
   /**
    * Opens the links in the selected folder, or the selected links in new tabs.
    */
   openSelectionInTabs: function PC_openLinksInTabs(aEvent) {
     var node = this._view.selectedNode;
--- a/browser/components/places/content/editBookmarkOverlay.js
+++ b/browser/components/places/content/editBookmarkOverlay.js
@@ -142,27 +142,23 @@ var gEditItemOverlay = {
                                        .getKeywordForBookmark(this._itemId));
         this._element("loadInSidebarCheckbox").checked =
           PlacesUtils.annotations.itemHasAnnotation(this._itemId,
                                                     PlacesUIUtils.LOAD_IN_SIDEBAR_ANNO);
       }
       else {
         this._uri = null;
         this._isLivemark = false;
-        PlacesUtils.livemarks.getLivemark(
-          {id: this._itemId },
-          (function (aStatus, aLivemark) {
-            if (Components.isSuccessCode(aStatus)) {
-              this._isLivemark = true;
-              this._initTextField("feedLocationField", aLivemark.feedURI.spec, true);
-              this._initTextField("siteLocationField", aLivemark.siteURI ? aLivemark.siteURI.spec : "", true);
-              this._showHideRows();
-            }
-          }).bind(this)
-        );
+        PlacesUtils.livemarks.getLivemark({id: this._itemId })
+          .then(aLivemark => {
+            this._isLivemark = true;
+            this._initTextField("feedLocationField", aLivemark.feedURI.spec, true);
+            this._initTextField("siteLocationField", aLivemark.siteURI ? aLivemark.siteURI.spec : "", true);
+            this._showHideRows();
+          }, () => undefined);
       }
 
       // folder picker
       this._initFolderMenuList(containerId);
 
       // description field
       this._initTextField("descriptionField", 
                           PlacesUIUtils.getItemDescription(this._itemId));
--- a/browser/components/places/content/treeView.js
+++ b/browser/components/places/content/treeView.js
@@ -781,29 +781,29 @@ PlacesTreeView.prototype = {
       let lastModifiedColumn =
         this._findColumnByType(this.COLUMN_TYPE_LASTMODIFIED);
       if (lastModifiedColumn && !lastModifiedColumn.hidden)
         this._tree.invalidateCell(row, lastModifiedColumn);
     }
   },
 
   _populateLivemarkContainer: function PTV__populateLivemarkContainer(aNode) {
-    PlacesUtils.livemarks.getLivemark({ id: aNode.itemId },
-      function (aStatus, aLivemark) {
+    PlacesUtils.livemarks.getLivemark({ id: aNode.itemId })
+      .then(aLivemark => {
         let placesNode = aNode;
         // Need to check containerOpen since getLivemark is async.
-        if (!Components.isSuccessCode(aStatus) || !placesNode.containerOpen)
+        if (!placesNode.containerOpen)
           return;
 
         let children = aLivemark.getNodesForContainer(placesNode);
         for (let i = 0; i < children.length; i++) {
           let child = children[i];
           this.nodeInserted(placesNode, child, i);
         }
-      }.bind(this));
+      }, Components.utils.reportError);
   },
 
   nodeTitleChanged: function PTV_nodeTitleChanged(aNode, aNewTitle) {
     this._invalidateCellValue(aNode, this.COLUMN_TYPE_TITLE);
   },
 
   nodeURIChanged: function PTV_nodeURIChanged(aNode, aNewURI) {
     this._invalidateCellValue(aNode, this.COLUMN_TYPE_URI);
@@ -842,29 +842,25 @@ PlacesTreeView.prototype = {
     this._invalidateCellValue(aNode, this.COLUMN_TYPE_KEYWORD);
   },
 
   nodeAnnotationChanged: function PTV_nodeAnnotationChanged(aNode, aAnno) {
     if (aAnno == PlacesUIUtils.DESCRIPTION_ANNO) {
       this._invalidateCellValue(aNode, this.COLUMN_TYPE_DESCRIPTION);
     }
     else if (aAnno == PlacesUtils.LMANNO_FEEDURI) {
-      PlacesUtils.livemarks.getLivemark(
-        { id: aNode.itemId },
-        function (aStatus, aLivemark) {
-          if (Components.isSuccessCode(aStatus)) {
-            this._controller.cacheLivemarkInfo(aNode, aLivemark);
-            let properties = this._cellProperties.get(aNode);
-            this._cellProperties.set(aNode, properties += " livemark ");
+      PlacesUtils.livemarks.getLivemark({ id: aNode.itemId })
+        .then(aLivemark => {
+          this._controller.cacheLivemarkInfo(aNode, aLivemark);
+          let properties = this._cellProperties.get(aNode);
+          this._cellProperties.set(aNode, properties += " livemark ");
 
-            // The livemark attribute is set as a cell property on the title cell.
-            this._invalidateCellValue(aNode, this.COLUMN_TYPE_TITLE);
-          }
-        }.bind(this)
-      );
+          // The livemark attribute is set as a cell property on the title cell.
+          this._invalidateCellValue(aNode, this.COLUMN_TYPE_TITLE);
+        }, Components.utils.reportError);
     }
   },
 
   nodeDateAddedChanged: function PTV_nodeDateAddedChanged(aNode, aNewValue) {
     this._invalidateCellValue(aNode, this.COLUMN_TYPE_DATEADDED);
   },
 
   nodeLastModifiedChanged:
@@ -878,36 +874,33 @@ PlacesTreeView.prototype = {
 
     if (PlacesUtils.nodeIsFolder(aNode) ||
         (this._flatList && aNode == this._rootNode)) {
       let queryOptions = PlacesUtils.asQuery(this._rootNode).queryOptions;
       if (queryOptions.excludeItems) {
         return;
       }
 
-      PlacesUtils.livemarks.getLivemark({ id: aNode.itemId },
-        function (aStatus, aLivemark) {
-          if (Components.isSuccessCode(aStatus)) {
-            let shouldInvalidate = 
-              !this._controller.hasCachedLivemarkInfo(aNode);
-            this._controller.cacheLivemarkInfo(aNode, aLivemark);
-            if (aNewState == Components.interfaces.nsINavHistoryContainerResultNode.STATE_OPENED) {
-              aLivemark.registerForUpdates(aNode, this);
-              // Prioritize the current livemark.
-              aLivemark.reload();
-              PlacesUtils.livemarks.reloadLivemarks();
-              if (shouldInvalidate)
-                this.invalidateContainer(aNode);
-            }
-            else {
-              aLivemark.unregisterForUpdates(aNode);
-            }
+      PlacesUtils.livemarks.getLivemark({ id: aNode.itemId })
+        .then(aLivemark => {
+          let shouldInvalidate = 
+            !this._controller.hasCachedLivemarkInfo(aNode);
+          this._controller.cacheLivemarkInfo(aNode, aLivemark);
+          if (aNewState == Components.interfaces.nsINavHistoryContainerResultNode.STATE_OPENED) {
+            aLivemark.registerForUpdates(aNode, this);
+            // Prioritize the current livemark.
+            aLivemark.reload();
+            PlacesUtils.livemarks.reloadLivemarks();
+            if (shouldInvalidate)
+              this.invalidateContainer(aNode);
           }
-        }.bind(this)
-      );
+          else {
+            aLivemark.unregisterForUpdates(aNode);
+          }
+        }, () => undefined);
     }
   },
 
   invalidateContainer: function PTV_invalidateContainer(aContainer) {
     NS_ASSERT(this._result, "Need to have a result to update");
     if (!this._tree)
       return;
 
@@ -1169,27 +1162,23 @@ PlacesTreeView.prototype = {
             properties += " hostContainer";
         }
         else if (nodeType == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER ||
                  nodeType == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT) {
           if (this._controller.hasCachedLivemarkInfo(node)) {
             properties += " livemark";
           }
           else {
-            PlacesUtils.livemarks.getLivemark(
-              { id: node.itemId },
-              function (aStatus, aLivemark) {
-                if (Components.isSuccessCode(aStatus)) {
-                  this._controller.cacheLivemarkInfo(node, aLivemark);
-                  properties += " livemark";
-                  // The livemark attribute is set as a cell property on the title cell.
-                  this._invalidateCellValue(node, this.COLUMN_TYPE_TITLE);
-                }
-              }.bind(this)
-            );
+            PlacesUtils.livemarks.getLivemark({ id: node.itemId })
+              .then(aLivemark => {
+                this._controller.cacheLivemarkInfo(node, aLivemark);
+                properties += " livemark";
+                // The livemark attribute is set as a cell property on the title cell.
+                this._invalidateCellValue(node, this.COLUMN_TYPE_TITLE);
+              }, () => undefined);
           }
         }
 
         if (itemId != -1) {
           let queryName = PlacesUIUtils.getLeftPaneQueryNameFromId(itemId);
           if (queryName)
             properties += " OrganizerQuery_" + queryName;
         }
--- a/services/sync/modules/engines/bookmarks.js
+++ b/services/sync/modules/engines/bookmarks.js
@@ -726,20 +726,20 @@ BookmarksStore.prototype = {
       let spinningCb = Async.makeSpinningCallback();
 
       let livemarkObj = {title: record.title,
                          parentId: record._parent,
                          index: PlacesUtils.bookmarks.DEFAULT_INDEX,
                          feedURI: Utils.makeURI(record.feedUri),
                          siteURI: siteURI,
                          guid: record.id};
-      PlacesUtils.livemarks.addLivemark(livemarkObj,
-        function (aStatus, aLivemark) {
-          spinningCb(null, [aStatus, aLivemark]);
-        });
+      PlacesUtils.livemarks.addLivemark(livemarkObj).then(
+        aLivemark => { spinningCb(null, [Components.results.NS_OK, aLivemark]) },
+        () => { spinningCb(null, [Components.results.NS_ERROR_UNEXPECTED, aLivemark]) }
+      );
 
       let [status, livemark] = spinningCb.wait();
       if (!Components.isSuccessCode(status)) {
         throw status;
       }
 
       this._log.debug("Created livemark " + livemark.id + " under " +
                       livemark.parentId + " as " + livemark.title +
--- a/services/sync/tps/extensions/tps/modules/bookmarks.jsm
+++ b/services/sync/tps/extensions/tps/modules/bookmarks.jsm
@@ -779,20 +779,20 @@ Livemark.prototype = {
                        title: this.props.livemark,
                        siteURI: siteURI,
                        feedURI: Services.io.newURI(this.props.feedUri, null, null),
                        index: PlacesUtils.bookmarks.DEFAULT_INDEX};
 
     // Until this can handle asynchronous creation, we need to spin.
     let spinningCb = Async.makeSpinningCallback();
 
-    PlacesUtils.livemarks.addLivemark(livemarkObj,
-      function (aStatus, aLivemark) {
-        spinningCb(null, [aStatus, aLivemark]);
-      });
+    PlacesUtils.livemarks.addLivemark(livemarkObj).then(
+      aLivemark => { spinningCb(null, [Components.results.NS_OK, aLivemark]) },
+      () => { spinningCb(null, [Components.results.NS_ERROR_UNEXPECTED, aLivemark]) }
+    );
 
     let [status, livemark] = spinningCb.wait();
     if (!Components.isSuccessCode(status)) {
       throw status;
     }
 
     this.props.item_id = livemark.id;
     return this.props.item_id;
--- a/toolkit/components/places/BookmarkHTMLUtils.jsm
+++ b/toolkit/components/places/BookmarkHTMLUtils.jsm
@@ -664,17 +664,17 @@ BookmarkImporter.prototype = {
         // The is a live bookmark.  We create it here since in HandleLinkBegin we
         // don't know the title.
         PlacesUtils.livemarks.addLivemark({
           "title": frame.previousText,
           "parentId": frame.containerId,
           "index": PlacesUtils.bookmarks.DEFAULT_INDEX,
           "feedURI": frame.previousFeed,
           "siteURI": frame.previousLink,
-        });
+        }).then(null, Cu.reportError);
       } else if (frame.previousLink) {
         // This is a common bookmark.
         PlacesUtils.bookmarks.setItemTitle(frame.previousId,
                                            frame.previousText);
       }
     } catch(e) {
     }
 
--- a/toolkit/components/places/BookmarkJSONUtils.jsm
+++ b/toolkit/components/places/BookmarkJSONUtils.jsm
@@ -381,25 +381,23 @@ BookmarkImporter.prototype = {
           if (feedURI) {
             PlacesUtils.livemarks.addLivemark({
               title: aData.title,
               feedURI: feedURI,
               parentId: aContainer,
               index: aIndex,
               lastModified: aData.lastModified,
               siteURI: siteURI
-            }, function(aStatus, aLivemark) {
-              if (Components.isSuccessCode(aStatus)) {
-                let id = aLivemark.id;
-                if (aData.dateAdded)
-                  PlacesUtils.bookmarks.setItemDateAdded(id, aData.dateAdded);
-                if (aData.annos && aData.annos.length)
-                  PlacesUtils.setAnnotationsForItem(id, aData.annos);
-              }
-            });
+            }).then(function (aLivemark) {
+              let id = aLivemark.id;
+              if (aData.dateAdded)
+                PlacesUtils.bookmarks.setItemDateAdded(id, aData.dateAdded);
+              if (aData.annos && aData.annos.length)
+                PlacesUtils.setAnnotationsForItem(id, aData.annos);
+            }, Cu.reportError);
           }
         } else {
           id = PlacesUtils.bookmarks.createFolder(
                  aContainer, aData.title, aIndex);
           folderIdMap[aData.id] = id;
           // Process children
           if (aData.children) {
             for (let i = 0; i < aData.children.length; i++) {
--- a/toolkit/components/places/PlacesUtils.jsm
+++ b/toolkit/components/places/PlacesUtils.jsm
@@ -2190,39 +2190,33 @@ PlacesCreateLivemarkTransaction.prototyp
   doTransaction: function CLTXN_doTransaction()
   {
     PlacesUtils.livemarks.addLivemark(
       { title: this.item.title
       , feedURI: this.item.feedURI
       , parentId: this.item.parentId
       , index: this.item.index
       , siteURI: this.item.siteURI
-      },
-      (function(aStatus, aLivemark) {
-        if (Components.isSuccessCode(aStatus)) {
-          this.item.id = aLivemark.id;
-          if (this.item.annotations && this.item.annotations.length > 0) {
-            PlacesUtils.setAnnotationsForItem(this.item.id,
-                                              this.item.annotations);
-          }
+      }).then(aLivemark => {
+        this.item.id = aLivemark.id;
+        if (this.item.annotations && this.item.annotations.length > 0) {
+          PlacesUtils.setAnnotationsForItem(this.item.id,
+                                            this.item.annotations);
         }
-      }).bind(this)
-    );
+      }, Cu.reportError);
   },
 
   undoTransaction: function CLTXN_undoTransaction()
   {
     // The getLivemark callback is expected to receive a failure status but it
     // is used just to serialize, so doesn't matter.
-    PlacesUtils.livemarks.getLivemark(
-      { id: this.item.id },
-      (function (aStatus, aLivemark) {
+    PlacesUtils.livemarks.getLivemark({ id: this.item.id })
+      .then(null, () => {
         PlacesUtils.bookmarks.removeItem(this.item.id);
-      }).bind(this)
-    );
+      });
   }
 };
 
 
 /**
  * Transaction for removing a livemark item.
  *
  * @param aLivemarkId
@@ -2250,55 +2244,45 @@ function PlacesRemoveLivemarkTransaction
     PlacesUtils.bookmarks.getItemLastModified(this.item.id);
 }
 
 PlacesRemoveLivemarkTransaction.prototype = {
   __proto__: BaseTransaction.prototype,
 
   doTransaction: function RLTXN_doTransaction()
   {
-    PlacesUtils.livemarks.getLivemark(
-      { id: this.item.id },
-      (function (aStatus, aLivemark) {
-        if (Components.isSuccessCode(aStatus)) {
-          this.item.feedURI = aLivemark.feedURI;
-          this.item.siteURI = aLivemark.siteURI;
-
-          PlacesUtils.bookmarks.removeItem(this.item.id);
-        }
-      }).bind(this)
-    );
+    PlacesUtils.livemarks.getLivemark({ id: this.item.id })
+      .then(aLivemark => {
+        this.item.feedURI = aLivemark.feedURI;
+        this.item.siteURI = aLivemark.siteURI;
+        PlacesUtils.bookmarks.removeItem(this.item.id);
+      }, Cu.reportError);
   },
 
   undoTransaction: function RLTXN_undoTransaction()
   {
     // Undo work must be serialized, otherwise won't be able to know the
     // feedURI and siteURI of the livemark.
     // The getLivemark callback is expected to receive a failure status but it
     // is used just to serialize, so doesn't matter.
-    PlacesUtils.livemarks.getLivemark(
-      { id: this.item.id },
-      (function () {
-        let addLivemarkCallback = (function(aStatus, aLivemark) {
-          if (Components.isSuccessCode(aStatus)) {
-            let itemId = aLivemark.id;
-            PlacesUtils.bookmarks.setItemDateAdded(itemId, this.item.dateAdded);
-            PlacesUtils.setAnnotationsForItem(itemId, this.item.annotations);
-          }
-        }).bind(this);
+    PlacesUtils.livemarks.getLivemark({ id: this.item.id })
+      .then(null, () => {
         PlacesUtils.livemarks.addLivemark({ parentId: this.item.parentId
                                           , title: this.item.title
                                           , siteURI: this.item.siteURI
                                           , feedURI: this.item.feedURI
                                           , index: this.item.index
                                           , lastModified: this.item.lastModified
-                                          },
-                                          addLivemarkCallback);
-      }).bind(this)
-    );
+                                          }).then(
+          aLivemark => {
+            let itemId = aLivemark.id;
+            PlacesUtils.bookmarks.setItemDateAdded(itemId, this.item.dateAdded);
+            PlacesUtils.setAnnotationsForItem(itemId, this.item.annotations);
+          }, Cu.reportError);
+      });
   }
 };
 
 
 /**
  * Transaction for moving an Item.
  *
  * @param aItemId
--- a/toolkit/components/places/mozIAsyncLivemarks.idl
+++ b/toolkit/components/places/mozIAsyncLivemarks.idl
@@ -22,32 +22,38 @@ interface mozIAsyncLivemarks : nsISuppor
    *        mozILivemarkInfo object containing at least title, parentId,
    *        index and feedURI of the livemark to create.
    * @param [optional] aCallback
    *        Invoked when the creation process is done.  In case of failure will
    *        receive an error code.
    * @return {Promise}
    * @throws NS_ERROR_INVALID_ARG if the supplied information is insufficient
    *         for the creation.
+   * @deprecated passing a callback is deprecated. Moreover, for backwards
+   *             compatibility reasons, when a callback is provided this method
+   *             won't return a promise.
    */
   jsval addLivemark(in jsval aLivemarkInfo,
                     [optional] in mozILivemarkCallback aCallback);
 
   /**
    * Removes an existing livemark.
    *
    * @param aLivemarkInfo
    *        mozILivemarkInfo object containing either an id or a guid of the
    *        livemark to remove.
    * @param [optional] aCallback
    *        Invoked when the removal process is done.  In case of failure will
    *        receive an error code.
    *
    * @return {Promise}
    * @throws NS_ERROR_INVALID_ARG if the id/guid is invalid.
+   * @deprecated passing a callback is deprecated. Moreover, for backwards
+   *             compatibility reasons, when a callback is provided this method
+   *             won't return a promise.
    */
   jsval removeLivemark(in jsval aLivemarkInfo,
                        [optional] in mozILivemarkCallback aCallback);
 
   /**
    * Gets an existing livemark.
    *
    * @param aLivemarkInfo
@@ -55,16 +61,19 @@ interface mozIAsyncLivemarks : nsISuppor
    *        livemark to retrieve.
    * @param [optional] aCallback
    *        Invoked when the fetching process is done.  In case of failure will
    *        receive an error code.
    *
    * @return {Promise}
    * @throws NS_ERROR_INVALID_ARG if the id/guid is invalid or an invalid
    *         callback is provided.
+   * @deprecated passing a callback is deprecated. Moreover, for backwards
+   *             compatibility reasons, when a callback is provided this method
+   *             won't return a promise.
    */
   jsval getLivemark(in jsval aLivemarkInfo,
                     [optional] in mozILivemarkCallback aCallback);
 
   /**
    * Reloads all livemarks if they are expired or if forced to do so.
    *
    * @param [optional]aForceUpdate
--- a/toolkit/components/places/nsLivemarkService.js
+++ b/toolkit/components/places/nsLivemarkService.js
@@ -13,16 +13,18 @@ const Cu = Components.utils;
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
                                   "resource://gre/modules/PlacesUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
                                   "resource://gre/modules/NetUtil.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Promise",
                                   "resource://gre/modules/Promise.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Deprecated",
+                                  "resource://gre/modules/Deprecated.jsm");
 
 ////////////////////////////////////////////////////////////////////////////////
 //// Services
 
 XPCOMUtils.defineLazyServiceGetter(this, "secMan",
                                    "@mozilla.org/scriptsecuritymanager;1",
                                    "nsIScriptSecurityManager");
 XPCOMUtils.defineLazyGetter(this, "asyncHistory", function () {
@@ -207,16 +209,22 @@ LivemarkService.prototype = {
         ("parentId" in aLivemarkInfo && aLivemarkInfo.parentId < 1) ||
         !("index" in aLivemarkInfo) || aLivemarkInfo.index < Ci.nsINavBookmarksService.DEFAULT_INDEX ||
         !(aLivemarkInfo.feedURI instanceof Ci.nsIURI) ||
         (aLivemarkInfo.siteURI && !(aLivemarkInfo.siteURI instanceof Ci.nsIURI)) ||
         (aLivemarkInfo.guid && !/^[a-zA-Z0-9\-_]{12}$/.test(aLivemarkInfo.guid))) {
       throw Cr.NS_ERROR_INVALID_ARG;
     }
 
+    if (aLivemarkCallback) {
+      Deprecated.warning("Passing a callback to Livermarks methods is deprecated. " +
+                         "Please use the returned promise instead.",
+                         "https://developer.mozilla.org/docs/Mozilla/JavaScript_code_modules/Promise.jsm");
+    }
+
     // The addition is done synchronously due to the fact importExport service
     // and JSON backups require that.  The notification is async though.
     // Once bookmarks are async, this may be properly fixed.
     let deferred = Promise.defer();
     let addLivemarkEx = null;
     let livemark = null;
     try {
       // Disallow adding a livemark inside another livemark.
@@ -253,48 +261,56 @@ LivemarkService.prototype = {
     finally {
       this._onCacheReady( () => {
         if (addLivemarkEx) {
           if (aLivemarkCallback) {
             try {
               aLivemarkCallback.onCompletion(addLivemarkEx.result, livemark);
             }
             catch(ex2) { }
+          } else {
+            deferred.reject(addLivemarkEx);
           }
-          deferred.reject(addLivemarkEx);
         }
         else {
           if (aLivemarkCallback) {
             try {
               aLivemarkCallback.onCompletion(Cr.NS_OK, livemark);
             }
             catch(ex2) { }
+          } else {
+            deferred.resolve(livemark);
           }
-          deferred.resolve(livemark);
         }
       });
     }
 
-    return deferred.promise;
+    return aLivemarkCallback ? null : deferred.promise;
   },
 
   removeLivemark: function LS_removeLivemark(aLivemarkInfo, aLivemarkCallback)
   {
     if (!aLivemarkInfo) {
       throw Cr.NS_ERROR_INVALID_ARG;
     }
 
     // Accept either a guid or an id.
     let id = aLivemarkInfo.guid || aLivemarkInfo.id;
     if (("guid" in aLivemarkInfo && !/^[a-zA-Z0-9\-_]{12}$/.test(aLivemarkInfo.guid)) ||
         ("id" in aLivemarkInfo && aLivemarkInfo.id < 1) ||
         !id) {
       throw Cr.NS_ERROR_INVALID_ARG;
     }
 
+    if (aLivemarkCallback) {
+      Deprecated.warning("Passing a callback to Livermarks methods is deprecated. " +
+                         "Please use the returned promise instead.",
+                         "https://developer.mozilla.org/docs/Mozilla/JavaScript_code_modules/Promise.jsm");
+    }
+
     // Convert the guid to an id.
     if (id in this._guids) {
       id = this._guids[id];
     }
 
     let deferred = Promise.defer();
     let removeLivemarkEx = null;
     try {
@@ -309,32 +325,34 @@ LivemarkService.prototype = {
     finally {
       this._onCacheReady( () => {
         if (removeLivemarkEx) {
           if (aLivemarkCallback) {
             try {
               aLivemarkCallback.onCompletion(removeLivemarkEx.result, null);
             }
             catch(ex2) { }
+          } else {
+            deferred.reject(removeLivemarkEx);
           }
-          deferred.reject(removeLivemarkEx);
         }
         else {
           if (aLivemarkCallback) {
             try {
               aLivemarkCallback.onCompletion(Cr.NS_OK, null);
             }
             catch(ex2) { }
+          } else {
+            deferred.resolve();
           }
-          deferred.resolve();
         }
       });
     }
 
-    return deferred.promise;
+    return aLivemarkCallback ? null : deferred.promise;
   },
 
   _reloaded: [],
   _reloadNextLivemark: function LS__reloadNextLivemark()
   {
     this._reloading = false;
     // Find first livemark to be reloaded.
     for (let id in this._livemarks) {
@@ -375,41 +393,49 @@ LivemarkService.prototype = {
     // Accept either a guid or an id.
     let id = aLivemarkInfo.guid || aLivemarkInfo.id;
     if (("guid" in aLivemarkInfo && !/^[a-zA-Z0-9\-_]{12}$/.test(aLivemarkInfo.guid)) ||
         ("id" in aLivemarkInfo && aLivemarkInfo.id < 1) ||
         !id) {
       throw Cr.NS_ERROR_INVALID_ARG;
     }
 
+    if (aLivemarkCallback) {
+      Deprecated.warning("Passing a callback to Livermarks methods is deprecated. " +
+                         "Please use the returned promise instead.",
+                         "https://developer.mozilla.org/docs/Mozilla/JavaScript_code_modules/Promise.jsm");
+    }
+
     let deferred = Promise.defer();
     this._onCacheReady( () => {
       // Convert the guid to an id.
       if (id in this._guids) {
         id = this._guids[id];
       }
       if (id in this._livemarks) {
         if (aLivemarkCallback) {
           try {
             aLivemarkCallback.onCompletion(Cr.NS_OK, this._livemarks[id]);
           } catch (ex) {}
+        } else {
+          deferred.resolve(this._livemarks[id]);
         }
-        deferred.resolve(this._livemarks[id]);
       }
       else {
         if (aLivemarkCallback) {
           try {
             aLivemarkCallback.onCompletion(Cr.NS_ERROR_INVALID_ARG, null);
           } catch (ex) { }
+        } else {
+          deferred.reject(Components.Exception("", Cr.NS_ERROR_INVALID_ARG));
         }
-        deferred.reject(Components.Exception("", Cr.NS_ERROR_INVALID_ARG));
       }
     });
 
-    return deferred.promise;
+    return aLivemarkCallback ? null : deferred.promise;
   },
 
   //////////////////////////////////////////////////////////////////////////////
   //// nsINavBookmarkObserver
 
   onBeginUpdateBatch:  function () {},
   onEndUpdateBatch:    function () {},
   onItemVisited:       function () {},
--- a/toolkit/components/places/tests/chrome/test_303567.xul
+++ b/toolkit/components/places/tests/chrome/test_303567.xul
@@ -50,20 +50,18 @@ function runTest()
 {
   function testLivemark(aLivemarkData) {
     PlacesUtils.livemarks.addLivemark(
       { title: "foo"
       , parentId: PlacesUtils.toolbarFolderId
       , index: PlacesUtils.bookmarks.DEFAULT_INDEX
       , feedURI: aLivemarkData.feedURI
       , siteURI: aLivemarkData.siteURI
-      },
-      function (aStatus, aLivemark) {
-        ok(Components.isSuccessCode(aStatus), "Get livemark");
-
+      })
+      .then(function (aLivemark) {
         is (aLivemark.feedURI.spec, aLivemarkData.feedURI.spec,
             "Get correct feedURI");
         if (aLivemarkData.siteURI) {
           is (aLivemark.siteURI.spec, aLivemarkData.siteURI.spec,
               "Get correct siteURI");
         }
         else {
           is (aLivemark.siteURI, null, "Get correct siteURI");
@@ -79,18 +77,20 @@ function runTest()
           });
 
           PlacesUtils.bookmarks.removeItem(aLivemark.id);
 
           if (aLivemark.feedURI.equals(LIVEMARKS[LIVEMARKS.length - 1].feedURI)) {
             SimpleTest.finish();
           }          
         });
+      }, function () {
+        is(true, false, "Should not fail adding a livemark");
       }
-    )
+    );
   }
 
   LIVEMARKS.forEach(testLivemark);
 }
 
 function waitForLivemarkLoad(aLivemark, aCallback) {
   // Don't need a real node here.
   let node = {};
--- a/toolkit/components/places/tests/chrome/test_341972a.xul
+++ b/toolkit/components/places/tests/chrome/test_341972a.xul
@@ -32,29 +32,30 @@ function runTest() {
   const FEEDSITESPEC = "http://example.org/"; 
 
   PlacesUtils.livemarks.addLivemark(
     { title: "foo"
     , parentId: PlacesUtils.toolbarFolderId
     , index: PlacesUtils.bookmarks.DEFAULT_INDEX
     , feedURI: NetUtil.newURI(FEEDSPEC)
     , siteURI: NetUtil.newURI(INITIALSITESPEC)
-    },
-    function (aStatus, aLivemark) {
-      ok(Components.isSuccessCode(aStatus), "Get livemark");
+    })
+    .then(function (aLivemark) {
       is(aLivemark.siteURI.spec, INITIALSITESPEC,
          "Has correct initial livemark site URI");
 
       waitForLivemarkLoad(aLivemark, function (aLivemark) {
         is(aLivemark.siteURI.spec, FEEDSITESPEC,
            "livemark site URI set to value in feed");
 
         PlacesUtils.bookmarks.removeItem(aLivemark.id);
         SimpleTest.finish();
       });
+    }, function () {
+      is(true, false, "Should not fail adding a livemark");
     }
   );
 }
 
 function waitForLivemarkLoad(aLivemark, aCallback) {
   // Don't need a real node here.
   let node = {};
   let resultObserver = {
--- a/toolkit/components/places/tests/chrome/test_341972b.xul
+++ b/toolkit/components/places/tests/chrome/test_341972b.xul
@@ -30,28 +30,29 @@ function runTest() {
   const FEEDSPEC = "http://mochi.test:8888/tests/toolkit/components/places/tests/chrome/sample_feed.atom";
   const FEEDSITESPEC = "http://example.org/"; 
 
   PlacesUtils.livemarks.addLivemark(
     { title: "foo"
     , parentId: PlacesUtils.toolbarFolderId
     , index: PlacesUtils.bookmarks.DEFAULT_INDEX
     , feedURI: NetUtil.newURI(FEEDSPEC)
-    },
-    function (aStatus, aLivemark) {
-      ok(Components.isSuccessCode(aStatus), "Get livemark");
+    })
+    .then(function (aLivemark) {
       is(aLivemark.siteURI, null, "Has null livemark site URI");
 
       waitForLivemarkLoad(aLivemark, function (aLivemark) {
         is(aLivemark.siteURI.spec, FEEDSITESPEC,
            "livemark site URI set to value in feed");
 
         PlacesUtils.bookmarks.removeItem(aLivemark.id);
         SimpleTest.finish();
       });
+    }, function () {
+      is(true, false, "Should not fail adding a livemark");
     }
   );
 }
 
 function waitForLivemarkLoad(aLivemark, aCallback) {
   // Don't need a real node here.
   let node = {};
   let resultObserver = {
--- a/toolkit/components/places/tests/chrome/test_342484.xul
+++ b/toolkit/components/places/tests/chrome/test_342484.xul
@@ -31,32 +31,32 @@ function runTest() {
   const GOOD_URLS = ["http://example.org/first", "http://example.org/last"];
 
   PlacesUtils.livemarks.addLivemark(
     { title: "foo"
     , parentId: PlacesUtils.toolbarFolderId
     , index: PlacesUtils.bookmarks.DEFAULT_INDEX
     , feedURI: NetUtil.newURI(FEEDSPEC)
     , siteURI: NetUtil.newURI("http:/mochi.test/")
-    },
-    function (aStatus, aLivemark) {
-      ok(Components.isSuccessCode(aStatus), "Get livemark");
-
+    })
+    .then(function (aLivemark) {
       waitForLivemarkLoad(aLivemark, function (aLivemark) {
         let nodes = aLivemark.getNodesForContainer({});
 
         is(nodes.length, 2, "Created the two good livemark items");
         for (let i = 0; i < nodes.length; ++i) {
           let node = nodes[i];
           ok(GOOD_URLS.indexOf(node.uri) != -1, "livemark item created with bad uri " + node.uri);
         }
 
         PlacesUtils.bookmarks.removeItem(aLivemark.id);
         SimpleTest.finish();
       });
+    }, function () {
+      is(true, false, "Should not fail adding a livemark");
     }
   );
 }
 
 function waitForLivemarkLoad(aLivemark, aCallback) {
   // Don't need a real node here.
   let node = {};
   let resultObserver = {
--- a/toolkit/components/places/tests/chrome/test_381357.xul
+++ b/toolkit/components/places/tests/chrome/test_381357.xul
@@ -30,30 +30,30 @@ function runTest() {
   const FEEDSPEC = "http://mochi.test:8888/tests/toolkit/components/places/tests/chrome/rss_as_html.rss";
 
   PlacesUtils.livemarks.addLivemark(
     { title: "foo"
     , parentId: PlacesUtils.toolbarFolderId
     , index: PlacesUtils.bookmarks.DEFAULT_INDEX
     , feedURI: NetUtil.newURI(FEEDSPEC)
     , siteURI: NetUtil.newURI("http:/mochi.test/")
-    },
-    function (aStatus, aLivemark) {
-      ok(Components.isSuccessCode(aStatus), "Get livemark");
-
+    })
+    .then(function (aLivemark) {
       waitForLivemarkLoad(aLivemark, function (aLivemark) {
         let nodes = aLivemark.getNodesForContainer({});
-        ok(Components.isSuccessCode(aStatus), "Get livemark entries");
 
         is(nodes[0].title, "The First Title",
            "livemark site URI set to value in feed");
 
         PlacesUtils.bookmarks.removeItem(aLivemark.id);
         SimpleTest.finish();
       });
+    }, function () {
+      is(true, false, "Should not fail adding a livemark");
+      SimpleTest.finish();
     }
   );
 }
 
 function waitForLivemarkLoad(aLivemark, aCallback) {
   // Don't need a real node here.
   let node = {};
   let resultObserver = {
--- a/toolkit/components/places/tests/chrome/test_reloadLivemarks.xul
+++ b/toolkit/components/places/tests/chrome/test_reloadLivemarks.xul
@@ -52,58 +52,68 @@ function runTest()
     PlacesUtils.livemarks.reloadLivemarks();
   });
 }
 
 function addLivemarks(aCallback) {
   info("Adding livemarks");
   let count = gLivemarks.length;
   gLivemarks.forEach(function(aLivemarkData) {
-    PlacesUtils.livemarks.addLivemark(aLivemarkData,
-      function (aStatus, aLivemark) {
-        ok(Components.isSuccessCode(aStatus), "Add livemark should succeed");
+    PlacesUtils.livemarks.addLivemark(aLivemarkData)
+      .then(function (aLivemark) {
+        ok(aLivemark.feedURI.equals(aLivemarkData.feedURI), "Livemark added");
         aLivemarkData.id = aLivemark.id;
         if (--count == 0) {
           aCallback();
         }
-      }
-    );
+      },
+      function () {
+        is(true, false, "Should not fail adding a livemark.");
+        aCallback();
+      });
   });
 }
 
 function reloadLivemarks(aForceUpdate, aCallback) {
   info("Reloading livemarks with forceUpdate: " + aForceUpdate);
   let count = gLivemarks.length;
   gLivemarks.forEach(function(aLivemarkData) {
-    PlacesUtils.livemarks.getLivemark(aLivemarkData,
-      function (aStatus, aLivemark) {
-        ok(Components.isSuccessCode(aStatus), "Get livemark should succeed");
+    PlacesUtils.livemarks.getLivemark(aLivemarkData)
+      .then(aLivemark => {
+        ok(aLivemark.feedURI.equals(aLivemarkData.feedURI), "Livemark found");
         aLivemarkData._observer = new resultObserver(aLivemark, function() {
           if (++count == gLivemarks.length) {
             aCallback();
           }
         });
         if (--count == 0) {
           PlacesUtils.livemarks.reloadLivemarks(aForceUpdate);
         }
+      },
+      function() {
+        is(true, false, "Should not fail getting a livemark.");
+        aCallback();
       }
     );
   });
 }
 
 function removeLivemarks(aCallback) {
   info("Removing livemarks");
   let count = gLivemarks.length;
   gLivemarks.forEach(function(aLivemarkData) {
-    PlacesUtils.livemarks.removeLivemark(aLivemarkData,
-      function (aStatus, aLivemark) {
-        ok(Components.isSuccessCode(aStatus), "Remove livemark should succeed");
+    PlacesUtils.livemarks.removeLivemark(aLivemarkData).then(
+      function (aLivemark) {
         if (--count == 0) {
           aCallback();
         }
+      },
+      function() {
+        is(true, false, "Should not fail adding a livemark.");
+        aCallback();
       }
     );
   });
 }
 
 function resultObserver(aLivemark, aCallback) {
   this._node = {};
   this._livemark = aLivemark;
--- a/toolkit/components/places/tests/queries/head_queries.js
+++ b/toolkit/components/places/tests/queries/head_queries.js
@@ -157,17 +157,17 @@ function task_populateDB(aArray)
           }
 
           if (qdata.isLivemark) {
             PlacesUtils.livemarks.addLivemark({ title: qdata.title
                                               , parentId: qdata.parentFolder
                                               , index: qdata.index
                                               , feedURI: uri(qdata.feedURI)
                                               , siteURI: uri(qdata.uri)
-                                              });
+                                              }).then(null, do_throw);
           }
 
           if (qdata.isBookmark) {
             let itemId = PlacesUtils.bookmarks.insertBookmark(qdata.parentFolder,
                                                               uri(qdata.uri),
                                                               qdata.index,
                                                               qdata.title);
             if (qdata.keyword)
--- a/toolkit/components/places/tests/unit/test_384370.js
+++ b/toolkit/components/places/tests/unit/test_384370.js
@@ -108,17 +108,17 @@ function populate() {
   for each(let {uri: u, title: t} in bookmarkData) {
     PlacesUtils.bookmarks.insertBookmark(PlacesUtils.bookmarks.toolbarFolder,
                                          u, PlacesUtils.bookmarks.DEFAULT_INDEX, t);
   }
 }
 
 function validate() {
   yield testCanonicalBookmarks();
-  testToolbarFolder();
+  yield testToolbarFolder();
   testUnfiledBookmarks();
   testTags();
 }
 
 // Tests a bookmarks datastore that has a set of bookmarks, etc
 // that flex each supported field and feature.
 function testCanonicalBookmarks() {
   // query to see if the deleted folder and items have been imported
@@ -212,26 +212,21 @@ function testToolbarFolder() {
   // child count (add 2 for pre-existing items)
   do_check_eq(toolbar.childCount, bookmarkData.length + 2);
   
   // livemark
   var livemark = toolbar.getChild(1);
   // title
   do_check_eq("Latest Headlines", livemark.title);
 
-  PlacesUtils.livemarks.getLivemark(
-    { id: livemark.itemId },
-    function (aStatus, aLivemark) {
-      do_check_true(Components.isSuccessCode(aStatus));
-      do_check_eq("http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/",
-                  aLivemark.siteURI.spec);
-      do_check_eq("http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
-                  aLivemark.feedURI.spec);
-    }
-  );
+  let foundLivemark = yield PlacesUtils.livemarks.getLivemark({ id: livemark.itemId });
+  do_check_eq("http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/",
+              foundLivemark.siteURI.spec);
+  do_check_eq("http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
+              foundLivemark.feedURI.spec);
 
   // test added bookmark data
   var child = toolbar.getChild(2);
   do_check_eq(child.uri, bookmarkData[0].uri.spec);
   do_check_eq(child.title, bookmarkData[0].title);
   child = toolbar.getChild(3);
   do_check_eq(child.uri, bookmarkData[1].uri.spec);
   do_check_eq(child.title, bookmarkData[1].title);
--- a/toolkit/components/places/tests/unit/test_bookmarks_html.js
+++ b/toolkit/components/places/tests/unit/test_bookmarks_html.js
@@ -358,23 +358,19 @@ function checkItem(aExpected, aNode)
                                  .getItemAnnotation(id, PlacesUtils.POST_DATA_ANNO),
                       aExpected.postData);
           break;
         case "charset":
           let testURI = NetUtil.newURI(aNode.uri);
           do_check_eq((yield PlacesUtils.getCharsetForURI(testURI)), aExpected.charset);
           break;
         case "feedUrl":
-          yield PlacesUtils.livemarks.getLivemark(
-            { id: id },
-            (aStatus, aLivemark) => {
-              do_check_true(Components.isSuccessCode(aStatus));
-              do_check_eq(aLivemark.siteURI.spec, aExpected.url);
-              do_check_eq(aLivemark.feedURI.spec, aExpected.feedUrl);
-            });
+          let livemark = yield PlacesUtils.livemarks.getLivemark({ id: id });
+          do_check_eq(livemark.siteURI.spec, aExpected.url);
+          do_check_eq(livemark.feedURI.spec, aExpected.feedUrl);
           break;
         case "children":
           let folder = aNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
           do_check_eq(folder.hasChildren, aExpected.children.length > 0);
           folder.containerOpen = true;
           do_check_eq(folder.childCount, aExpected.children.length);
 
           aExpected.children.forEach(function (item, index) checkItem(item, folder.getChild(index)));
--- a/toolkit/components/places/tests/unit/test_bookmarks_html_corrupt.js
+++ b/toolkit/components/places/tests/unit/test_bookmarks_html_corrupt.js
@@ -149,29 +149,21 @@ function database_check() {
     toolbar.containerOpen = true;
     do_check_eq(toolbar.childCount, 3);
 
     // livemark
     var livemark = toolbar.getChild(1);
     // title
     do_check_eq("Latest Headlines", livemark.title);
 
-    let deferGetLivemark = Promise.defer();
-    PlacesUtils.livemarks.getLivemark(
-      { id: livemark.itemId },
-      function (aStatus, aLivemark) {
-        do_check_true(Components.isSuccessCode(aStatus));
-        do_check_eq("http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/",
-                    aLivemark.siteURI.spec);
-        do_check_eq("http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
-                    aLivemark.feedURI.spec);
-        deferGetLivemark.resolve();
-      }
-    );
-    yield deferGetLivemark.promise;
+    let foundLivemark = yield PlacesUtils.livemarks.getLivemark({ id: livemark.itemId });
+    do_check_eq("http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/",
+                foundLivemark.siteURI.spec);
+    do_check_eq("http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
+                foundLivemark.feedURI.spec);
 
     // cleanup
     toolbar.containerOpen = false;
 
     // UNFILED BOOKMARKS
     query.setFolders([bs.unfiledBookmarksFolder], 1);
     result = hs.executeQuery(query, hs.getNewQueryOptions());
     var unfiledBookmarks = result.root;
--- a/toolkit/components/places/tests/unit/test_bookmarks_json.js
+++ b/toolkit/components/places/tests/unit/test_bookmarks_json.js
@@ -187,23 +187,19 @@ function checkItem(aExpected, aNode) {
           do_check_eq(PlacesUtils.annotations.getItemAnnotation(
                       id, PlacesUtils.POST_DATA_ANNO), aExpected.postData);
           break;
         case "charset":
           let testURI = NetUtil.newURI(aNode.uri);
           do_check_eq((yield PlacesUtils.getCharsetForURI(testURI)), aExpected.charset);
           break;
         case "feedUrl":
-          yield PlacesUtils.livemarks.getLivemark(
-            { id: id },
-            (aStatus, aLivemark) => {
-              do_check_true(Components.isSuccessCode(aStatus));
-              do_check_eq(aLivemark.siteURI.spec, aExpected.url);
-              do_check_eq(aLivemark.feedURI.spec, aExpected.feedUrl);
-            });
+          let livemark = yield PlacesUtils.livemarks.getLivemark({ id: id });
+          do_check_eq(livemark.siteURI.spec, aExpected.url);
+          do_check_eq(livemark.feedURI.spec, aExpected.feedUrl);
           break;
         case "children":
           let folder = aNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
           do_check_eq(folder.hasChildren, aExpected.children.length > 0);
           folder.containerOpen = true;
           do_check_eq(folder.childCount, aExpected.children.length);
 
           aExpected.children.forEach(function (item, index) checkItem(item, folder.getChild(index)));
--- a/toolkit/components/places/tests/unit/test_bug636917_isLivemark.js
+++ b/toolkit/components/places/tests/unit/test_bug636917_isLivemark.js
@@ -8,24 +8,21 @@ function run_test()
   do_test_pending();
 
   let annoObserver = {
     onItemAnnotationSet:
     function AO_onItemAnnotationSet(aItemId, aAnnotationName)
     {
       if (aAnnotationName == PlacesUtils.LMANNO_FEEDURI) {
         PlacesUtils.annotations.removeObserver(this);
-        PlacesUtils.livemarks.getLivemark(
-          { id: aItemId },
-          function (aStatus, aLivemark) {
-            do_check_true(Components.isSuccessCode(aStatus));
+        PlacesUtils.livemarks.getLivemark({ id: aItemId })
+          .then(aLivemark => {
             PlacesUtils.bookmarks.removeItem(aItemId);
             do_test_finished();
-          }
-        );
+          }, do_throw);
       }
     },
   
     onItemAnnotationRemoved: function () {},
     onPageAnnotationSet: function() {},
     onPageAnnotationRemoved: function() {},
     QueryInterface: XPCOMUtils.generateQI([
       Ci.nsIAnnotationObserver
@@ -34,10 +31,10 @@ function run_test()
   PlacesUtils.annotations.addObserver(annoObserver, false);
   PlacesUtils.livemarks.addLivemark(
     { title: "livemark title"
     , parentId: PlacesUtils.unfiledBookmarksFolderId
     , index: PlacesUtils.bookmarks.DEFAULT_INDEX
     , siteURI: uri("http://example.com/")
     , feedURI: uri("http://example.com/rdf")
     }
-  );
+  ).then(null, do_throw);
 }
--- a/toolkit/components/places/tests/unit/test_mozIAsyncLivemarks.js
+++ b/toolkit/components/places/tests/unit/test_mozIAsyncLivemarks.js
@@ -173,211 +173,135 @@ add_task(function test_addLivemark_noCal
     { title: "test"
     , parentId: PlacesUtils.unfiledBookmarksFolderId
     , index: PlacesUtils.bookmarks.DEFAULT_INDEX
     , feedURI: FEED_URI });
   do_check_true(onItemAddedCalled);
 });
 
 
-add_task(function test_addLivemark_noSiteURI_callback_succeeds()
+add_task(function test_addLivemark_noSiteURI_succeeds()
 {
-  let checkLivemark = aLivemark => {
-    do_check_true(aLivemark.id > 0);
-    do_check_valid_places_guid(aLivemark.guid);
-    do_check_eq(aLivemark.title, "test");
-    do_check_eq(aLivemark.parentId, PlacesUtils.unfiledBookmarksFolderId);
-    do_check_eq(aLivemark.index, PlacesUtils.bookmarks.getItemIndex(aLivemark.id));
-    do_check_eq(aLivemark.lastModified, PlacesUtils.bookmarks.getItemLastModified(aLivemark.id));
-    do_check_true(aLivemark.feedURI.equals(FEED_URI));
-    do_check_eq(aLivemark.siteURI, null);
-  };
-
-  // The deprecated callback is called before resolving the promise.
-  let callbackCalled = false;
   let livemark = yield PlacesUtils.livemarks.addLivemark(
     { title: "test"
     , parentId: PlacesUtils.unfiledBookmarksFolderId
     , index: PlacesUtils.bookmarks.DEFAULT_INDEX
     , feedURI: FEED_URI
-    },
-    (aStatus, aLivemark) => {
-      callbackCalled = true;
-      do_check_true(Components.isSuccessCode(aStatus));
-      checkLivemark(aLivemark);
-    } );
-  do_check_true(callbackCalled);
-  checkLivemark(livemark);
+    });
+  do_check_true(livemark.id > 0);
+  do_check_valid_places_guid(livemark.guid);
+  do_check_eq(livemark.title, "test");
+  do_check_eq(livemark.parentId, PlacesUtils.unfiledBookmarksFolderId);
+  do_check_eq(livemark.index, PlacesUtils.bookmarks.getItemIndex(livemark.id));
+  do_check_eq(livemark.lastModified, PlacesUtils.bookmarks.getItemLastModified(livemark.id));
+  do_check_true(livemark.feedURI.equals(FEED_URI));
+  do_check_eq(livemark.siteURI, null);
 });
 
-add_task(function test_addLivemark_callback_succeeds()
+add_task(function test_addLivemark_succeeds()
 {
-  let checkLivemark = aLivemark => {
-    do_check_true(aLivemark.id > 0);
-    do_check_valid_places_guid(aLivemark.guid);
-    do_check_eq(aLivemark.title, "test");
-    do_check_eq(aLivemark.parentId, PlacesUtils.unfiledBookmarksFolderId);
-    do_check_eq(aLivemark.index, PlacesUtils.bookmarks.getItemIndex(aLivemark.id));
-    do_check_eq(aLivemark.lastModified, PlacesUtils.bookmarks.getItemLastModified(aLivemark.id));
-    do_check_true(aLivemark.feedURI.equals(FEED_URI));
-    do_check_true(aLivemark.siteURI.equals(SITE_URI));
-    do_check_true(PlacesUtils.annotations
-                             .itemHasAnnotation(aLivemark.id,
-                                                PlacesUtils.LMANNO_FEEDURI));
-    do_check_true(PlacesUtils.annotations
-                             .itemHasAnnotation(aLivemark.id,
-                                                PlacesUtils.LMANNO_SITEURI));
-  };
-
-  // The deprecated callback is called before resolving the promise.
-  let callbackCalled = false;
   let livemark = yield PlacesUtils.livemarks.addLivemark(
     { title: "test"
     , parentId: PlacesUtils.unfiledBookmarksFolderId
     , index: PlacesUtils.bookmarks.DEFAULT_INDEX
     , feedURI: FEED_URI
     , siteURI: SITE_URI
-    },
-    (aStatus, aLivemark) => {
-      callbackCalled = true;
-      do_check_true(Components.isSuccessCode(aStatus));
-      checkLivemark(aLivemark);
-    } );
-  do_check_true(callbackCalled);
-  checkLivemark(livemark);
+    });
+
+  do_check_true(livemark.id > 0);
+  do_check_valid_places_guid(livemark.guid);
+  do_check_eq(livemark.title, "test");
+  do_check_eq(livemark.parentId, PlacesUtils.unfiledBookmarksFolderId);
+  do_check_eq(livemark.index, PlacesUtils.bookmarks.getItemIndex(livemark.id));
+  do_check_eq(livemark.lastModified, PlacesUtils.bookmarks.getItemLastModified(livemark.id));
+  do_check_true(livemark.feedURI.equals(FEED_URI));
+  do_check_true(livemark.siteURI.equals(SITE_URI));
+  do_check_true(PlacesUtils.annotations
+                           .itemHasAnnotation(livemark.id,
+                                              PlacesUtils.LMANNO_FEEDURI));
+  do_check_true(PlacesUtils.annotations
+                           .itemHasAnnotation(livemark.id,
+                                              PlacesUtils.LMANNO_SITEURI));
 });
 
-add_task(function test_addLivemark_bogusid_callback_succeeds()
+add_task(function test_addLivemark_bogusid_succeeds()
 {
-  let checkLivemark = aLivemark => {
-    do_check_true(aLivemark.id > 0);
-    do_check_neq(aLivemark.id, 100);
-  };
-
-  // The deprecated callback is called before resolving the promise.
-  let callbackCalled = false;
   let livemark = yield PlacesUtils.livemarks.addLivemark(
     { id: 100 // Should be ignored.
     , title: "test"
     , parentId: PlacesUtils.unfiledBookmarksFolderId
     , index: PlacesUtils.bookmarks.DEFAULT_INDEX
     , feedURI: FEED_URI
     , siteURI: SITE_URI
-    },
-    (aStatus, aLivemark) => {
-      callbackCalled = true;
-      do_check_true(Components.isSuccessCode(aStatus));
-      checkLivemark(aLivemark);
-    } );
-  do_check_true(callbackCalled);
-  checkLivemark(livemark);
+    });
+  do_check_true(livemark.id > 0);
+  do_check_neq(livemark.id, 100);
 });
 
-add_task(function test_addLivemark_bogusParent_callback_fails()
+add_task(function test_addLivemark_bogusParent_fails()
 {
-  // The deprecated callback is called before resolving the promise.
-  let callbackCalled = false;
   try {
     yield PlacesUtils.livemarks.addLivemark(
       { title: "test"
       , parentId: 187
       , index: PlacesUtils.bookmarks.DEFAULT_INDEX
       , feedURI: FEED_URI
-      },
-      (aStatus, aLivemark) => {
-        callbackCalled = true;
-        do_check_false(Components.isSuccessCode(aStatus));
-        do_check_eq(aLivemark, null);
-      } );
+      });
     do_throw("Adding a livemark with a bogus parent should fail");
-  }
-  catch(ex) {
-    do_check_true(callbackCalled);
-  }
+  } catch(ex) {}
 });
 
-add_task(function test_addLivemark_intoLivemark_callback_fails()
+add_task(function test_addLivemark_intoLivemark_fails()
 {
-  // The deprecated callback is called before resolving the promise.
-  let callbackCalled = false;
   let livemark = yield PlacesUtils.livemarks.addLivemark(
     { title: "test"
     , parentId: PlacesUtils.unfiledBookmarksFolderId
     , index: PlacesUtils.bookmarks.DEFAULT_INDEX
     , feedURI: FEED_URI
-    },
-    (aStatus, aLivemark) => {
-      callbackCalled = true;
-      do_check_true(Components.isSuccessCode(aStatus));
-    } );
-  do_check_true(callbackCalled);
+    });
   do_check_true(Boolean(livemark));
 
-  callbackCalled = false;
   try {
     yield PlacesUtils.livemarks.addLivemark(
       { title: "test"
       , parentId: livemark.id
       , index: PlacesUtils.bookmarks.DEFAULT_INDEX
       , feedURI: FEED_URI
-      },
-      (aStatus, aLivemark) => {
-        callbackCalled = true;
-        do_check_false(Components.isSuccessCode(aStatus));
-        do_check_eq(aLivemark, null);
-      } );
+      });
     do_throw("Adding a livemark into a livemark should fail");
-  }
-  catch(ex) {
-    do_check_true(callbackCalled);
-  }
+  } catch(ex) {}
 });
 
-add_task(function test_addLivemark_forceGuid_callback_succeeds()
+add_task(function test_addLivemark_forceGuid_succeeds()
 {
   let checkLivemark = aLivemark => {
     do_check_eq(aLivemark.guid, "1234567890AB");
     do_check_guid_for_bookmark(aLivemark.id, "1234567890AB");
   };
 
-  // The deprecated callback is called before resolving the promise.
-  let callbackCalled = false;
   let livemark = yield PlacesUtils.livemarks.addLivemark(
     { title: "test"
     , parentId: PlacesUtils.unfiledBookmarksFolderId
     , index: PlacesUtils.bookmarks.DEFAULT_INDEX
     , feedURI: FEED_URI
     , guid: "1234567890AB"
-    },
-    (aStatus, aLivemark) => {
-      callbackCalled = true;
-      do_check_true(Components.isSuccessCode(aStatus));
-      checkLivemark(aLivemark);
-    } );
-  do_check_true(callbackCalled);
+    });
   checkLivemark(livemark);
 });
 
-add_task(function test_addLivemark_lastModified_callback_succeeds()
+add_task(function test_addLivemark_lastModified_succeeds()
 {
   let now = Date.now() * 1000;
-  let callbackCalled = false;
   let livemark = yield PlacesUtils.livemarks.addLivemark(
     { title: "test"
     , parentId: PlacesUtils.unfiledBookmarksFolderId
     , index: PlacesUtils.bookmarks.DEFAULT_INDEX
     , feedURI: FEED_URI
     , lastModified: now
-    },
-    (aStatus, aLivemark) => {
-      callbackCalled = true;
-      do_check_true(Components.isSuccessCode(aStatus));
-      do_check_eq(aLivemark.lastModified, now);
-    } );
-  do_check_true(callbackCalled);
+    });
   do_check_eq(livemark.lastModified, now);
 });
 
 add_task(function test_removeLivemark_emptyObject_throws()
 {
   try {
     yield PlacesUtils.livemarks.removeLivemark({});
     do_throw("Invoking removeLivemark with empty object should throw");
@@ -393,29 +317,21 @@ add_task(function test_removeLivemark_no
     do_throw("Invoking removeLivemark with no valid id should throw");
   } catch (ex) {
     do_check_eq(ex.result, Cr.NS_ERROR_INVALID_ARG);
   }
 });
 
 add_task(function test_removeLivemark_nonExistent_fails()
 {
-  let callbackCalled = false;
   try {
-    yield PlacesUtils.livemarks.removeLivemark(
-      { id: 1337 },
-      (aStatus, aLivemark) => {
-        callbackCalled = true;
-        do_check_false(Components.isSuccessCode(aStatus));
-        do_check_eq(aLivemark, null);
-      } );
+    yield PlacesUtils.livemarks.removeLivemark({ id: 1337 });
     do_throw("Removing a non-existent livemark should fail");
   }
   catch(ex) {
-    do_check_true(callbackCalled);
   }
 });
 
 add_task(function test_removeLivemark_guid_succeeds()
 {
   let livemark = yield PlacesUtils.livemarks.addLivemark(
     { title: "test"
     , parentId: PlacesUtils.unfiledBookmarksFolderId
@@ -464,108 +380,70 @@ add_task(function test_getLivemark_noVal
     do_throw("Invoking getLivemark with no valid id should throw");
   } catch (ex) {
     do_check_eq(ex.result, Cr.NS_ERROR_INVALID_ARG);
   }
 });
 
 add_task(function test_getLivemark_nonExistentId_fails()
 {
-  let callbackCalled = false;
   try {
-    yield PlacesUtils.livemarks.getLivemark({ id: 1234 },
-      (aStatus, aLivemark) => {
-        callbackCalled = true;
-        do_check_false(Components.isSuccessCode(aStatus));
-        do_check_eq(aLivemark, null);
-      } );
+    yield PlacesUtils.livemarks.getLivemark({ id: 1234 });
     do_throw("getLivemark for a non existent id should fail");
   }
-  catch(ex) {
-    do_check_true(callbackCalled);
-  }
+  catch(ex) {}
 });
 
 add_task(function test_getLivemark_nonExistentGUID_fails()
 {
-  let callbackCalled = false;
   try {
-    yield PlacesUtils.livemarks.getLivemark({ guid: "34567890ABCD" },
-      (aStatus, aLivemark) => {
-        callbackCalled = true;
-        do_check_false(Components.isSuccessCode(aStatus));
-        do_check_eq(aLivemark, null);
-      } );
+    yield PlacesUtils.livemarks.getLivemark({ guid: "34567890ABCD" });
     do_throw("getLivemark for a non-existent guid should fail");
   }
-  catch(ex) {
-    do_check_true(callbackCalled);
-  }
+  catch(ex) {}
 });
 
 add_task(function test_getLivemark_guid_succeeds()
 {
   yield PlacesUtils.livemarks.addLivemark(
     { title: "test"
     , parentId: PlacesUtils.unfiledBookmarksFolderId
     , index: PlacesUtils.bookmarks.DEFAULT_INDEX
     , feedURI: FEED_URI
     , guid: "34567890ABCD" });
 
-  let checkLivemark = aLivemark => {
-    do_check_eq(aLivemark.title, "test");
-    do_check_eq(aLivemark.parentId, PlacesUtils.unfiledBookmarksFolderId);
-    do_check_eq(aLivemark.index, PlacesUtils.bookmarks.getItemIndex(aLivemark.id));
-    do_check_true(aLivemark.feedURI.equals(FEED_URI));
-    do_check_eq(aLivemark.siteURI, null);
-    do_check_eq(aLivemark.guid, "34567890ABCD");
-  };
-
   // invalid id to check the guid wins.
   let livemark =
-    yield PlacesUtils.livemarks.getLivemark({ id: 789, guid: "34567890ABCD" },
-      (aStatus, aLivemark) => {
-        callbackCalled = true;
-        do_check_true(Components.isSuccessCode(aStatus));
-        checkLivemark(aLivemark)
-      } );
+    yield PlacesUtils.livemarks.getLivemark({ id: 789, guid: "34567890ABCD" });
 
-  do_check_true(callbackCalled);
-  checkLivemark(livemark);
+  do_check_eq(livemark.title, "test");
+  do_check_eq(livemark.parentId, PlacesUtils.unfiledBookmarksFolderId);
+  do_check_eq(livemark.index, PlacesUtils.bookmarks.getItemIndex(livemark.id));
+  do_check_true(livemark.feedURI.equals(FEED_URI));
+  do_check_eq(livemark.siteURI, null);
+  do_check_eq(livemark.guid, "34567890ABCD");
 });
 
 add_task(function test_getLivemark_id_succeeds()
 {
   let livemark = yield PlacesUtils.livemarks.addLivemark(
     { title: "test"
     , parentId: PlacesUtils.unfiledBookmarksFolderId
     , index: PlacesUtils.bookmarks.DEFAULT_INDEX
     , feedURI: FEED_URI
     });
 
-  let checkLivemark = aLivemark => {
-    do_check_eq(aLivemark.title, "test");
-    do_check_eq(aLivemark.parentId, PlacesUtils.unfiledBookmarksFolderId);
-    do_check_eq(aLivemark.index, PlacesUtils.bookmarks.getItemIndex(aLivemark.id));
-    do_check_true(aLivemark.feedURI.equals(FEED_URI));
-    do_check_eq(aLivemark.siteURI, null);
-    do_check_guid_for_bookmark(aLivemark.id, aLivemark.guid);
-  };
+  livemark = yield PlacesUtils.livemarks.getLivemark({ id: livemark.id });
 
-  let callbackCalled = false;
-  livemark = yield PlacesUtils.livemarks.getLivemark(
-    { id: livemark.id },
-    (aStatus, aLivemark) => {
-      callbackCalled = true;
-      do_check_true(Components.isSuccessCode(aStatus));
-      checkLivemark(aLivemark);
-    } );
-
-  do_check_true(callbackCalled);
-  checkLivemark(livemark);
+  do_check_eq(livemark.title, "test");
+  do_check_eq(livemark.parentId, PlacesUtils.unfiledBookmarksFolderId);
+  do_check_eq(livemark.index, PlacesUtils.bookmarks.getItemIndex(livemark.id));
+  do_check_true(livemark.feedURI.equals(FEED_URI));
+  do_check_eq(livemark.siteURI, null);
+  do_check_guid_for_bookmark(livemark.id, livemark.guid);
 });
 
 add_task(function test_getLivemark_removeItem_contention()
 {
   PlacesUtils.livemarks.addLivemark({ title: "test"
                                     , parentId: PlacesUtils.unfiledBookmarksFolderId
                                     , index: PlacesUtils.bookmarks.DEFAULT_INDEX
                                     , feedURI: FEED_URI
@@ -574,36 +452,24 @@ add_task(function test_getLivemark_remov
   PlacesUtils.livemarks.addLivemark({ title: "test"
                                     , parentId: PlacesUtils.unfiledBookmarksFolderId
                                     , index: PlacesUtils.bookmarks.DEFAULT_INDEX
                                     , feedURI: FEED_URI
                                     });
   let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId,
                                                 PlacesUtils.bookmarks.DEFAULT_INDEX);
 
-  let checkLivemark = (aLivemark) => {
-    do_check_eq(aLivemark.title, "test");
-    do_check_eq(aLivemark.parentId, PlacesUtils.unfiledBookmarksFolderId);
-    do_check_eq(aLivemark.index, PlacesUtils.bookmarks.getItemIndex(aLivemark.id));
-    do_check_true(aLivemark.feedURI.equals(FEED_URI));
-    do_check_eq(aLivemark.siteURI, null);
-    do_check_guid_for_bookmark(aLivemark.id, aLivemark.guid);
-  };
+  let livemark = yield PlacesUtils.livemarks.getLivemark({ id: id });
 
-  let callbackCalled = false;
-  let livemark = yield PlacesUtils.livemarks.getLivemark(
-    { id: id },
-    (aStatus, aLivemark) => {
-      callbackCalled = true;
-      do_check_true(Components.isSuccessCode(aStatus));
-      checkLivemark(aLivemark);
-    } );
-
-  do_check_true(callbackCalled);
-  checkLivemark(livemark);
+  do_check_eq(livemark.title, "test");
+  do_check_eq(livemark.parentId, PlacesUtils.unfiledBookmarksFolderId);
+  do_check_eq(livemark.index, PlacesUtils.bookmarks.getItemIndex(livemark.id));
+  do_check_true(livemark.feedURI.equals(FEED_URI));
+  do_check_eq(livemark.siteURI, null);
+  do_check_guid_for_bookmark(livemark.id, livemark.guid);
 });
 
 add_task(function test_title_change()
 {
   let livemark = yield PlacesUtils.livemarks.addLivemark(
     { title: "test"
     , parentId: PlacesUtils.unfiledBookmarksFolderId
     , index: PlacesUtils.bookmarks.DEFAULT_INDEX