Bug 1362970 - Part 2 - Script-generated patch to convert .then(null, ...) to .catch(...). r=florian
authorPaolo Amadini <paolo.mozmail@amadzone.org>
Mon, 19 Jun 2017 11:32:37 +0100
changeset 364909 1075b94a522dbadf874f224312fa542d3fecdc9d
parent 364908 c210c53f73fc50d58164eb8c895966137ddedca6
child 364910 e8a9a2014b798fe11361d9e5896465d5b135bcb4
push id91642
push userpaolo.mozmail@amadzone.org
push dateTue, 20 Jun 2017 11:42:31 +0000
treeherdermozilla-inbound@e8a9a2014b79 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersflorian
bugs1362970
milestone56.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 1362970 - Part 2 - Script-generated patch to convert .then(null, ...) to .catch(...). r=florian Changes to Promise tests designed to test .then(null) have been reverted, and the browser/extensions directory was excluded because the projects it contains have a separate process for accepting changes. MozReview-Commit-ID: 1buqgX1EP4P
addon-sdk/source/lib/sdk/addon/runner.js
addon-sdk/source/lib/sdk/l10n/loader.js
addon-sdk/source/test/addons/page-mod-debugger-post/main.js
addon-sdk/source/test/addons/page-mod-debugger-pre/main.js
addon-sdk/source/test/addons/places/lib/test-places-host.js
addon-sdk/source/test/addons/private-browsing-supported/test-selection.js
addon-sdk/source/test/addons/private-browsing-supported/test-sidebar.js
addon-sdk/source/test/addons/private-browsing-supported/test-window-tabs.js
addon-sdk/source/test/addons/private-browsing-supported/test-windows.js
addon-sdk/source/test/tabs/test-firefox-tabs.js
addon-sdk/source/test/test-addon-window.js
addon-sdk/source/test/test-child_process.js
addon-sdk/source/test/test-native-loader.js
addon-sdk/source/test/test-panel.js
addon-sdk/source/test/test-promise.js
addon-sdk/source/test/test-ui-toggle-button.js
addon-sdk/source/test/test-window-utils-private-browsing.js
browser/base/content/aboutaccounts/aboutaccounts.js
browser/base/content/browser.js
browser/base/content/sanitizeDialog.js
browser/components/customizableui/CustomizeMode.jsm
browser/components/customizableui/content/panelUI.js
browser/components/downloads/DownloadsCommon.jsm
browser/components/downloads/DownloadsTaskbar.jsm
browser/components/nsBrowserGlue.js
browser/components/places/content/browserPlacesViews.js
browser/components/places/content/controller.js
browser/components/places/content/menu.xml
browser/components/places/content/moveBookmarks.js
browser/components/places/content/places.js
browser/components/places/content/treeView.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadLastDir_c.js
browser/components/uitour/UITour.jsm
browser/components/uitour/test/browser_UITour.js
browser/components/uitour/test/browser_UITour2.js
browser/experiments/test/addons/experiment-racybranch/bootstrap.js
browser/modules/AboutHome.jsm
devtools/client/canvasdebugger/panel.js
devtools/client/canvasdebugger/test/head.js
devtools/client/commandline/test/helpers.js
devtools/client/debugger/panel.js
devtools/client/debugger/test/mochitest/browser_dbg_addonactor.js
devtools/client/debugger/test/mochitest/browser_dbg_auto-pretty-print-02.js
devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-01.js
devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-02.js
devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-03.js
devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-04.js
devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-05.js
devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-06.js
devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-07.js
devtools/client/debugger/test/mochitest/browser_dbg_breadcrumbs-access.js
devtools/client/debugger/test/mochitest/browser_dbg_break-on-dom-event-01.js
devtools/client/debugger/test/mochitest/browser_dbg_break-on-dom-event-02.js
devtools/client/debugger/test/mochitest/browser_dbg_chrome-debugging.js
devtools/client/debugger/test/mochitest/browser_dbg_clean-exit-window.js
devtools/client/debugger/test/mochitest/browser_dbg_closure-inspection.js
devtools/client/debugger/test/mochitest/browser_dbg_debugger-statement.js
devtools/client/debugger/test/mochitest/browser_dbg_editor-contextmenu.js
devtools/client/debugger/test/mochitest/browser_dbg_editor-mode.js
devtools/client/debugger/test/mochitest/browser_dbg_event-listeners-01.js
devtools/client/debugger/test/mochitest/browser_dbg_event-listeners-02.js
devtools/client/debugger/test/mochitest/browser_dbg_event-listeners-03.js
devtools/client/debugger/test/mochitest/browser_dbg_iframes.js
devtools/client/debugger/test/mochitest/browser_dbg_interrupts.js
devtools/client/debugger/test/mochitest/browser_dbg_jump-to-function-definition.js
devtools/client/debugger/test/mochitest/browser_dbg_listaddons.js
devtools/client/debugger/test/mochitest/browser_dbg_listtabs-01.js
devtools/client/debugger/test/mochitest/browser_dbg_multiple-windows.js
devtools/client/debugger/test/mochitest/browser_dbg_navigation.js
devtools/client/debugger/test/mochitest/browser_dbg_no-page-sources.js
devtools/client/debugger/test/mochitest/browser_dbg_optimized-out-vars.js
devtools/client/debugger/test/mochitest/browser_dbg_pause-exceptions-01.js
devtools/client/debugger/test/mochitest/browser_dbg_pause-exceptions-02.js
devtools/client/debugger/test/mochitest/browser_dbg_paused-keybindings.js
devtools/client/debugger/test/mochitest/browser_dbg_pretty-print-11.js
devtools/client/debugger/test/mochitest/browser_dbg_promises-allocation-stack.js
devtools/client/debugger/test/mochitest/browser_dbg_promises-chrome-allocation-stack.js
devtools/client/debugger/test/mochitest/browser_dbg_promises-fulfillment-stack.js
devtools/client/debugger/test/mochitest/browser_dbg_promises-rejection-stack.js
devtools/client/debugger/test/mochitest/browser_dbg_reload-preferred-script-03.js
devtools/client/debugger/test/mochitest/browser_dbg_search-basic-02.js
devtools/client/debugger/test/mochitest/browser_dbg_search-basic-03.js
devtools/client/debugger/test/mochitest/browser_dbg_search-global-01.js
devtools/client/debugger/test/mochitest/browser_dbg_search-global-03.js
devtools/client/debugger/test/mochitest/browser_dbg_search-global-04.js
devtools/client/debugger/test/mochitest/browser_dbg_search-global-05.js
devtools/client/debugger/test/mochitest/browser_dbg_search-global-06.js
devtools/client/debugger/test/mochitest/browser_dbg_search-popup-jank.js
devtools/client/debugger/test/mochitest/browser_dbg_search-sources-01.js
devtools/client/debugger/test/mochitest/browser_dbg_search-sources-02.js
devtools/client/debugger/test/mochitest/browser_dbg_search-sources-03.js
devtools/client/debugger/test/mochitest/browser_dbg_search-symbols.js
devtools/client/debugger/test/mochitest/browser_dbg_searchbox-help-popup-01.js
devtools/client/debugger/test/mochitest/browser_dbg_searchbox-help-popup-02.js
devtools/client/debugger/test/mochitest/browser_dbg_source-maps-01.js
devtools/client/debugger/test/mochitest/browser_dbg_source-maps-02.js
devtools/client/debugger/test/mochitest/browser_dbg_source-maps-03.js
devtools/client/debugger/test/mochitest/browser_dbg_source-maps-04.js
devtools/client/debugger/test/mochitest/browser_dbg_sources-contextmenu-01.js
devtools/client/debugger/test/mochitest/browser_dbg_sources-contextmenu-02.js
devtools/client/debugger/test/mochitest/browser_dbg_sources-keybindings.js
devtools/client/debugger/test/mochitest/browser_dbg_stack-contextmenu-02.js
devtools/client/debugger/test/mochitest/browser_dbg_tabactor-01.js
devtools/client/debugger/test/mochitest/browser_dbg_tabactor-02.js
devtools/client/debugger/test/mochitest/browser_dbg_variables-view-accessibility.js
devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-getset-01.js
devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-getset-02.js
devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-value-01.js
devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-value-02.js
devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-watch.js
devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-01.js
devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-02.js
devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-03.js
devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-04.js
devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-05.js
devtools/client/debugger/test/mochitest/browser_dbg_variables-view-frame-parameters-01.js
devtools/client/debugger/test/mochitest/browser_dbg_variables-view-frame-parameters-02.js
devtools/client/debugger/test/mochitest/browser_dbg_variables-view-frame-parameters-03.js
devtools/client/debugger/test/mochitest/browser_dbg_variables-view-frame-with.js
devtools/client/debugger/test/mochitest/browser_dbg_variables-view-large-array-buffer.js
devtools/client/debugger/test/mochitest/browser_dbg_variables-view-webidl.js
devtools/client/debugger/test/mochitest/browser_dbg_watch-expressions-02.js
devtools/client/debugger/test/mochitest/doc_promise-get-allocation-stack.html
devtools/client/debugger/test/mochitest/doc_promise.html
devtools/client/debugger/views/variable-bubble-view.js
devtools/client/devtools-startup.js
devtools/client/framework/test/browser_toolbox_custom_host.js
devtools/client/framework/test/browser_toolbox_raise.js
devtools/client/framework/test/browser_toolbox_sidebar.js
devtools/client/framework/test/browser_toolbox_sidebar_events.js
devtools/client/framework/toolbox.js
devtools/client/inspector/computed/computed.js
devtools/client/inspector/fonts/fonts.js
devtools/client/inspector/inspector.js
devtools/client/inspector/markup/markup.js
devtools/client/inspector/markup/views/element-editor.js
devtools/client/inspector/markup/views/text-editor.js
devtools/client/inspector/rules/models/element-style.js
devtools/client/inspector/rules/rules.js
devtools/client/inspector/shared/highlighters-overlay.js
devtools/client/netmonitor/src/har/har-exporter.js
devtools/client/scratchpad/scratchpad.js
devtools/client/scratchpad/test/browser_scratchpad_pprint-02.js
devtools/client/scratchpad/test/browser_scratchpad_pprint.js
devtools/client/shadereditor/panel.js
devtools/client/shadereditor/shadereditor.js
devtools/client/shadereditor/test/head.js
devtools/client/shared/developer-toolbar.js
devtools/client/shared/redux/middleware/task.js
devtools/client/sourceeditor/autocomplete.js
devtools/client/styleeditor/StyleEditorUI.jsm
devtools/client/styleeditor/StyleSheetEditor.jsm
devtools/client/webaudioeditor/panel.js
devtools/client/webconsole/console-output.js
devtools/client/webconsole/test/browser_console_optimized_out_vars.js
devtools/client/webconsole/test/browser_webconsole_split.js
devtools/client/webide/content/webide.js
devtools/client/webide/modules/app-manager.js
devtools/client/webide/test/test_device_preferences.html
devtools/client/webide/test/test_device_runtime.html
devtools/client/webide/test/test_duplicate_import.html
devtools/client/webide/test/test_import.html
devtools/server/actors/script.js
devtools/server/actors/source.js
devtools/server/actors/utils/TabSources.js
devtools/server/main.js
devtools/server/tests/mochitest/inspector-helpers.js
devtools/server/tests/unit/test_actor-registry-actor.js
devtools/server/tests/unit/test_blackboxing-06.js
devtools/server/tests/unit/test_promise_state-03.js
devtools/server/tests/unit/test_promises_client_getdependentpromises.js
devtools/server/tests/unit/test_protocol_children.js
devtools/server/tests/unit/test_protocol_longstring.js
devtools/server/tests/unit/test_protocol_simple.js
devtools/server/tests/unit/test_sourcemaps-10.js
devtools/server/tests/unit/test_sourcemaps-11.js
devtools/shared/apps/app-actor-front.js
devtools/shared/fronts/device.js
devtools/shared/gcli/templater.js
devtools/shared/protocol.js
devtools/shared/tests/mochitest/test_eventemitter_basic.html
devtools/shared/tests/unit/test_async-utils.js
devtools/shared/transport/tests/unit/test_client_server_bulk.js
dom/crypto/test/test_WebCrypto.html
dom/promise/tests/test_on_promise_settled.html
dom/promise/tests/test_on_promise_settled_duplicates.html
dom/promise/tests/unit/test_monitor_uncaught.js
dom/security/test/csp/file_service_worker.html
mobile/android/chrome/content/aboutDownloads.js
mobile/android/chrome/content/browser.js
mobile/android/components/AddonUpdateService.js
mobile/android/components/Snippets.js
netwerk/protocol/http/UserAgentUpdates.jsm
netwerk/test/mochitests/test_user_agent_updates.html
security/manager/ssl/tests/mochitest/mixedcontent/test_bug383369.html
services/fxaccounts/FxAccounts.jsm
services/fxaccounts/tests/xpcshell/test_accounts.js
services/fxaccounts/tests/xpcshell/test_oauth_grant_client.js
services/fxaccounts/tests/xpcshell/test_profile_client.js
services/sync/modules/browserid_identity.js
services/sync/modules/engines/history.js
services/sync/tps/extensions/tps/resource/modules/bookmarks.jsm
testing/modules/Assert.jsm
toolkit/components/asyncshutdown/AsyncShutdown.jsm
toolkit/components/jsdownloads/src/DownloadCore.jsm
toolkit/components/jsdownloads/src/DownloadIntegration.jsm
toolkit/components/jsdownloads/src/DownloadLegacy.js
toolkit/components/jsdownloads/src/DownloadList.jsm
toolkit/components/jsdownloads/test/unit/head.js
toolkit/components/osfile/modules/osfile_async_front.jsm
toolkit/components/passwordmgr/LoginManagerContent.jsm
toolkit/components/passwordmgr/nsLoginManager.js
toolkit/components/places/Bookmarks.jsm
toolkit/components/places/PlacesUtils.jsm
toolkit/components/places/UnifiedComplete.js
toolkit/components/places/tests/unit/test_bookmarks_restore_notification.js
toolkit/components/thumbnails/PageThumbs.jsm
toolkit/content/contentAreaUtils.js
toolkit/modules/DeferredTask.jsm
toolkit/modules/ZipUtils.jsm
toolkit/mozapps/downloads/nsHelperAppDlg.js
toolkit/mozapps/extensions/AddonManager.jsm
toolkit/mozapps/extensions/DeferredSave.jsm
toolkit/mozapps/extensions/internal/AddonRepository.jsm
toolkit/mozapps/extensions/internal/GMPProvider.jsm
toolkit/mozapps/extensions/internal/XPIInstall.jsm
toolkit/mozapps/extensions/internal/XPIProvider.jsm
toolkit/mozapps/extensions/internal/XPIProviderUtils.js
toolkit/mozapps/extensions/test/browser/head.js
--- a/addon-sdk/source/lib/sdk/addon/runner.js
+++ b/addon-sdk/source/lib/sdk/addon/runner.js
@@ -65,28 +65,28 @@ function startup(reason, options) {
 
     // NOTE: Module is intentionally required only now because it relies
     // on existence of hidden window, which does not exists until startup.
     let { ready } = require('../addon/window');
     // Load localization manifest and .properties files.
     // Run the addon even in case of error (best effort approach)
     require('../l10n/loader').
       load(rootURI).
-      then(null, function failure(error) {
+      catch(function failure(error) {
         if (!isNative)
           console.info("Error while loading localization: " + error.message);
       }).
       then(function onLocalizationReady(data) {
         // Exports data to a pseudo module so that api-utils/l10n/core
         // can get access to it
         definePseudo(options.loader, '@l10n/data', data ? data : null);
         return ready;
       }).then(function() {
         run(options);
-      }).then(null, console.exception);
+      }).catch(console.exception);
     return void 0; // otherwise we raise a warning, see bug 910304
   });
 }
 
 function run(options) {
   try {
     // Try initializing HTML localization before running main module. Just print
     // an exception in case of error, instead of preventing addon to be run.
--- a/addon-sdk/source/lib/sdk/l10n/loader.js
+++ b/addon-sdk/source/lib/sdk/l10n/loader.js
@@ -10,17 +10,17 @@ module.metadata = {
 const { Cc, Ci } = require("chrome");
 lazyRequire(this, "./locale", "getPreferedLocales", "findClosestLocale");
 lazyRequire(this, "../net/url", "readURI");
 lazyRequire(this, "../core/promise", "resolve");
 
 function parseJsonURI(uri) {
   return readURI(uri).
     then(JSON.parse).
-    then(null, function (error) {
+    catch(function (error) {
       throw Error("Failed to parse locale file:\n" + uri + "\n" + error);
     });
 }
 
 // Returns the array stored in `locales.json` manifest that list available
 // locales files
 function getAvailableLocales(rootURI) {
   let uri = rootURI + "locales.json";
--- a/addon-sdk/source/test/addons/page-mod-debugger-post/main.js
+++ b/addon-sdk/source/test/addons/page-mod-debugger-post/main.js
@@ -38,17 +38,17 @@ exports.testDebugger = function(assert, 
           then(_ => { assert.pass('attachTabActorForUrl called'); return _; }).
           then(attachThread).
           then(testDebuggerStatement).
           then(_ => { assert.pass('testDebuggerStatement called') }).
           then(closeConnection).
           then(_ => { assert.pass('closeConnection called') }).
           then(_ => { tab.close() }).
           then(done).
-          then(null, aError => {
+          catch(aError => {
             ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
           });
       }
     });
   });
 }
 
 function attachThread([aGrip, aResponse]) {
--- a/addon-sdk/source/test/addons/page-mod-debugger-pre/main.js
+++ b/addon-sdk/source/test/addons/page-mod-debugger-pre/main.js
@@ -45,17 +45,17 @@ exports.testDebugger = function(assert, 
           then(_ => { assert.pass('attachTabActorForUrl called'); return _; }).
           then(attachThread).
           then(testDebuggerStatement).
           then(_ => { assert.pass('testDebuggerStatement called') }).
           then(closeConnection).
           then(_ => { assert.pass('closeConnection called') }).
           then(_ => { tab.close() }).
           then(done).
-          then(null, aError => {
+          catch(aError => {
             ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
           });
       }
     });
   });
 }
 
 function attachThread([aGrip, aResponse]) {
--- a/addon-sdk/source/test/addons/places/lib/test-places-host.js
+++ b/addon-sdk/source/test/addons/places/lib/test-places-host.js
@@ -61,17 +61,17 @@ exports.testBookmarksCreateFail = functi
     type: 'bookmark'
   }, {
     type: 'group',
     group: bmsrv.bookmarksMenuFolder
   }, {
     group: bmsrv.unfiledBookmarksFolder
   }];
   all(items.map(function (item) {
-    return send('sdk-places-bookmarks-create', item).then(null, function (reason) {
+    return send('sdk-places-bookmarks-create', item).catch(function (reason) {
       assert.ok(reason, 'bookmark create should fail');
     });
   })).then(done);
 };
 
 exports.testBookmarkLastUpdated = function (assert, done) {
   let timestamp;
   let item;
--- a/addon-sdk/source/test/addons/private-browsing-supported/test-selection.js
+++ b/addon-sdk/source/test/addons/private-browsing-supported/test-selection.js
@@ -228,24 +228,24 @@ exports["test PWPB Selection Listener"] 
           assert.ok(isFocused(window), "the window is focused");
           assert.ok(isPrivate(window), "the window should be a private window");
 
           assert.equal(selection.text, "fo");
 
           closeWindow(window).
             then(loader.unload).
             then(done).
-            then(null, assert.fail);
+            catch(assert.fail);
         });
       });
       return window;
     }).
     then(selectContentFirstDiv).
     then(dispatchSelectionEvent).
-    then(null, assert.fail);
+    catch(assert.fail);
 };
 
 exports["test PWPB Textarea OnSelect Listener"] = function(assert, done) {
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   open(URL, {private: true, title: "PWPB OnSelect Listener"}).
     then(function(window) {
@@ -258,24 +258,24 @@ exports["test PWPB Textarea OnSelect Lis
 
         // window should be focused, but force the focus anyhow.. see bug 841823
         focus(window).then(function() {
           assert.equal(selection.text, "noodles");
 
           closeWindow(window).
             then(loader.unload).
             then(done).
-            then(null, assert.fail);
+            catch(assert.fail);
         });
       });
       return window;
     }).
     then(selectTextarea).
     then(dispatchOnSelectEvent).
-    then(null, assert.fail);
+    catch(assert.fail);
 };
 
 exports["test PWPB Single DOM Selection"] = function(assert, done) {
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   open(URL, {private: true, title: "PWPB Single DOM Selection"}).
     then(selectFirstDiv).
@@ -299,17 +299,17 @@ exports["test PWPB Single DOM Selection"
         assert.equal(sel.html, "<div>foo</div>",
           "iterable selection.html with single DOM Selection works.");
       }
 
       assert.equal(selectionCount, 1,
         "One iterable selection");
 
       return closeWindow(window);
-    }).then(loader.unload).then(done).then(null, assert.fail);
+    }).then(loader.unload).then(done).catch(assert.fail);
 }
 
 exports["test PWPB Textarea Selection"] = function(assert, done) {
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   open(URL, {private: true, title: "PWPB Textarea Listener"}).
     then(selectTextarea).
@@ -335,17 +335,17 @@ exports["test PWPB Textarea Selection"] 
         assert.strictEqual(sel.html, null,
           "iterable selection.html with Textarea Selection works.");
       }
 
       assert.equal(selectionCount, 1,
         "One iterable selection");
 
       return closeWindow(window);
-    }).then(loader.unload).then(done).then(null, assert.fail);
+    }).then(loader.unload).then(done).catch(assert.fail);
 };
 
 exports["test PWPB Set HTML in Multiple DOM Selection"] = function(assert, done) {
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   open(URL, {private: true, title: "PWPB Set HTML in Multiple DOM Selection"}).
     then(selectAllDivs).
@@ -375,17 +375,17 @@ exports["test PWPB Set HTML in Multiple 
 
         selectionCount++;
       }
 
       assert.equal(selectionCount, 2,
         "Two iterable selections");
 
       return closeWindow(window);
-    }).then(loader.unload).then(done).then(null, assert.fail);
+    }).then(loader.unload).then(done).catch(assert.fail);
 };
 
 exports["test PWPB Set Text in Textarea Selection"] = function(assert, done) {
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   open(URL, {private: true, title: "test PWPB Set Text in Textarea Selection"}).
     then(selectTextarea).
@@ -412,17 +412,17 @@ exports["test PWPB Set Text in Textarea 
         assert.strictEqual(sel.html, null,
           "iterable selection.html with Textarea Selection works.");
       }
 
       assert.equal(selectionCount, 1,
         "One iterable selection");
 
       return closeWindow(window);
-    }).then(loader.unload).then(done).then(null, assert.fail);
+    }).then(loader.unload).then(done).catch(assert.fail);
 };
 
 // If the platform doesn't support the PBPW, we're replacing PBPW tests
 if (!require("sdk/private-browsing/utils").isWindowPBSupported) {
   module.exports = {
     "test PBPW Unsupported": function Unsupported (assert) {
       assert.pass("Private Window Per Browsing is not supported on this platform.");
     }
--- a/addon-sdk/source/test/addons/private-browsing-supported/test-sidebar.js
+++ b/addon-sdk/source/test/addons/private-browsing-supported/test-sidebar.js
@@ -35,17 +35,17 @@ exports.testSideBarIsInNewPrivateWindows
       assert.ok(isPrivate(window), 'the new window is private');
       assert.ok(!!ele, 'sidebar element was added');
 
       sidebar.destroy();
       assert.ok(!window.document.getElementById(makeID(testName)), 'sidebar id DNE');
       assert.ok(!startWindow.document.getElementById(makeID(testName)), 'sidebar id DNE');
 
       return close(window);
-  }).then(done).then(null, assert.fail);
+  }).then(done).catch(assert.fail);
 }
 
 // Disabled in order to land other fixes, see bug 910647 for further details.
 /*
 exports.testSidebarIsOpenInNewPrivateWindow = function(assert, done) {
   const { Sidebar } = require('sdk/ui/sidebar');
   let testName = 'testSidebarIsOpenInNewPrivateWindow';
   let window = getMostRecentBrowserWindow();
@@ -137,18 +137,18 @@ exports.testDestroyEdgeCaseBugWithPrivat
           assert.equal(isSidebarShowing(window), false, 'the sidebar is not showing');
 
           done();
         }
       })
 
       sidebar.show();
       assert.pass('showing the sidebar');
-    }).then(null, assert.fail);
-  }).then(null, assert.fail);
+    }).catch(assert.fail);
+  }).catch(assert.fail);
 }
 
 exports.testShowInPrivateWindow = function(assert, done) {
   const { Sidebar } = require('sdk/ui/sidebar');
   let testName = 'testShowInPrivateWindow';
   let window1 = getMostRecentBrowserWindow();
   let url = 'data:text/html;charset=utf-8,'+testName;
 
@@ -183,22 +183,22 @@ exports.testShowInPrivateWindow = functi
                   'the menuitem on the new window dne');
 
         // test old window state
         assert.equal(isSidebarShowing(window1), false, 'the old window sidebar is not showing');
         assert.equal(window1.document.getElementById(menuitemID),
                      null,
                      'the menuitem on the old window dne');
 
-        close(window).then(done).then(null, assert.fail);
+        close(window).then(done).catch(assert.fail);
       },
       function bad() {
         assert.fail('a successful show should not happen here..');
       });
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 }
 
 // If the module doesn't support the app we're being run in, require() will
 // throw.  In that case, remove all tests above from exports, and add one dummy
 // test that passes.
 try {
   require('sdk/ui/sidebar');
 }
--- a/addon-sdk/source/test/addons/private-browsing-supported/test-window-tabs.js
+++ b/addon-sdk/source/test/addons/private-browsing-supported/test-window-tabs.js
@@ -13,63 +13,63 @@ exports.testOpenTabWithPrivateActiveWind
 
   windowPromise(window, 'load').then(focus).then(function (window) {
     assert.ok(isPrivate(window), 'new window is private');
 
     tabs.open({
       url: 'about:blank',
       onOpen: function(tab) {
         assert.ok(isPrivate(tab), 'new tab is private');
-        close(window).then(done).then(null, assert.fail);
+        close(window).then(done).catch(assert.fail);
       }
     })
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 }
 
 exports.testOpenTabWithNonPrivateActiveWindowNoIsPrivateOption = function(assert, done) {
   let window = getMostRecentBrowserWindow().OpenBrowserWindow({ private: false });
 
   windowPromise(window, 'load').then(focus).then(function (window) {
     assert.equal(isPrivate(window), false, 'new window is not private');
 
     tabs.open({
       url: 'about:blank',
       onOpen: function(tab) {
         assert.equal(isPrivate(tab), false, 'new tab is not private');
-        close(window).then(done).then(null, assert.fail);
+        close(window).then(done).catch(assert.fail);
       }
     })
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 }
 
 exports.testOpenTabWithPrivateActiveWindowWithIsPrivateOptionTrue = function(assert, done) {
   let window = getMostRecentBrowserWindow().OpenBrowserWindow({ private: true });
 
   windowPromise(window, 'load').then(focus).then(function (window) {
     assert.ok(isPrivate(window), 'new window is private');
 
     tabs.open({
       url: 'about:blank',
       isPrivate: true,
       onOpen: function(tab) {
         assert.ok(isPrivate(tab), 'new tab is private');
-        close(window).then(done).then(null, assert.fail);
+        close(window).then(done).catch(assert.fail);
       }
     })
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 }
 
 exports.testOpenTabWithNonPrivateActiveWindowWithIsPrivateOptionFalse = function(assert, done) {
   let window = getMostRecentBrowserWindow().OpenBrowserWindow({ private: false });
 
   windowPromise(window, 'load').then(focus).then(function (window) {
     assert.equal(isPrivate(window), false, 'new window is not private');
 
     tabs.open({
       url: 'about:blank',
       isPrivate: false,
       onOpen: function(tab) {
         assert.equal(isPrivate(tab), false, 'new tab is not private');
-        close(window).then(done).then(null, assert.fail);
+        close(window).then(done).catch(assert.fail);
       }
     })
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 }
--- a/addon-sdk/source/test/addons/private-browsing-supported/test-windows.js
+++ b/addon-sdk/source/test/addons/private-browsing-supported/test-windows.js
@@ -69,17 +69,17 @@ exports.testWindowTrackerIgnoresPrivateW
       assert.pass('private window was closed');
 
       return makeEmptyBrowserWindow().then(function(window) {
         myNonPrivateWindowId = getInnerId(window);
         assert.notEqual(myPrivateWindowId, myNonPrivateWindowId, 'non private window was opened');
         return close(window);
       });
     });
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 };
 
 // Test setting activeWIndow and onFocus for private windows
 exports.testSettingActiveWindowDoesNotIgnorePrivateWindow = function(assert, done) {
   let browserWindow = WM.getMostRecentWindow("navigator:browser");
   let testSteps;
 
   assert.equal(winUtils.activeBrowserWindow, browserWindow,
@@ -141,17 +141,17 @@ exports.testSettingActiveWindowDoesNotIg
         continueAfterFocus(winUtils.activeWindow = browserWindow);
       },
       function() {
         assert.strictEqual(winUtils.activeBrowserWindow, browserWindow,
                           "Correct active browser window when pb mode is supported [4]");
         assert.strictEqual(winUtils.activeWindow, browserWindow,
                           "Correct active window when pb mode is supported [4]");
 
-        close(window).then(done).then(null, assert.fail);
+        close(window).then(done).catch(assert.fail);
       }
     ];
 
     function nextTest() {
       let args = arguments;
       if (testSteps.length) {
         require('sdk/timers').setTimeout(function() {
           (testSteps.shift()).apply(null, args);
@@ -231,10 +231,10 @@ exports.testWindowIteratorPrivateDefault
     assert.equal(isPrivate(winUtils.activeWindow), isWindowPBSupported);
     assert.equal(isPrivate(getMostRecentWindow()), isWindowPBSupported);
     assert.equal(isPrivate(browserWindows.activeWindow), isWindowPBSupported);
 
     assert.equal(browserWindows.length, 2, '2 windows open');
     assert.equal(windows(null, { includePrivate: true }).length, 2);
 
     return close(window);
-  }).then(done).then(null, assert.fail);
+  }).then(done).catch(assert.fail);
 };
--- a/addon-sdk/source/test/tabs/test-firefox-tabs.js
+++ b/addon-sdk/source/test/tabs/test-firefox-tabs.js
@@ -70,17 +70,17 @@ exports.testBrowserWindowCreationOnActiv
   tabs.once('activate', function onActivate(eventTab) {
     assert.ok(windows.activeWindow, "Is able to fetch activeWindow");
     gotActivate = true;
   });
 
   open().then(function(window) {
     assert.ok(gotActivate, "Received activate event");
     return close(window);
-  }).then(done).then(null, assert.fail);
+  }).then(done).catch(assert.fail);
 }
 
 // TEST: tab unloader
 exports.testAutomaticDestroyEventOpen = function(assert, done) {
   let called = false;
   let loader = Loader(module);
   let tabs2 = loader.require("sdk/tabs");
   tabs2.on('open', _ => called = true);
@@ -171,17 +171,17 @@ exports.testTabPropertiesInNewWindow = f
   });
 
   let tabs = loader.require('sdk/tabs');
   let { viewFor } = loader.require('sdk/view/core');
 
   let count = 0;
   function onReadyOrLoad (tab) {
     if (count++) {
-      close(getOwnerWindow(viewFor(tab))).then(done).then(null, assert.fail);
+      close(getOwnerWindow(viewFor(tab))).then(done).catch(assert.fail);
     }
   }
 
   let url = "data:text/html;charset=utf-8,<html><head><title>foo</title></head><body>foo</body></html>";
   tabs.open({
     inNewWindow: true,
     url: url,
     onReady: function(tab) {
@@ -264,17 +264,17 @@ exports.testTabContentTypeAndReload = fu
       url: url,
       onReady: function(tab) {
         if (tab.url === url) {
           assert.equal(tab.contentType, "text/html");
           tab.url = urlXML;
         }
         else {
           assert.equal(tab.contentType, "text/xml");
-          close(window).then(done).then(null, assert.fail);
+          close(window).then(done).catch(assert.fail);
         }
       }
     });
   });
 };
 
 // TEST: tabs iterator and length property
 exports.testTabsIteratorAndLength = function(assert, done) {
@@ -289,34 +289,34 @@ exports.testTabsIteratorAndLength = func
     tabs.open({
       url: url,
       onOpen: function(tab) {
         let count = 0;
         for (let t of tabs) count++;
         assert.equal(count, startCount + 3, "iterated tab count matches");
         assert.equal(startCount + 3, tabs.length, "iterated tab count matches length property");
 
-        close(window).then(done).then(null, assert.fail);
+        close(window).then(done).catch(assert.fail);
       }
     });
   });
 };
 
 // TEST: tab.url setter
 exports.testTabLocation = function(assert, done) {
   open().then(focus).then(function(window) {
     let url1 = "data:text/html;charset=utf-8,foo";
     let url2 = "data:text/html;charset=utf-8,bar";
 
     tabs.on('ready', function onReady(tab) {
       if (tab.url != url2)
         return;
       tabs.removeListener('ready', onReady);
       assert.pass("tab.load() loaded the correct url");
-      close(window).then(done).then(null, assert.fail);
+      close(window).then(done).catch(assert.fail);
     });
 
     tabs.open({
       url: url1,
       onOpen: function(tab) {
         tab.url = url2
       }
     });
@@ -360,20 +360,20 @@ exports.testTabMove = function(assert, d
     let url = "data:text/html;charset=utf-8,foo";
 
     tabs.open({
       url: url,
       onOpen: function(tab) {
         assert.equal(tab.index, 1, "tab index before move matches");
         tab.index = 0;
         assert.equal(tab.index, 0, "tab index after move matches");
-        close(window).then(done).then(null, assert.fail);
+        close(window).then(done).catch(assert.fail);
       }
     });
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 };
 
 exports.testIgnoreClosing = function*(assert) {
   let url = "data:text/html;charset=utf-8,foobar";
   let originalWindow = getMostRecentBrowserWindow();
 
   let window = yield open().then(focus);
 
@@ -476,17 +476,17 @@ exports.testOpenInNewWindow = function(a
 
       onFocus(newWindow).then(function() {
         assert.equal(getMostRecentBrowserWindow(), newWindow, "new window is active");
         assert.equal(tab.url, url, "URL of the new tab matches");
         assert.equal(newWindow.content.location, url, "URL of new tab in new window matches");
         assert.equal(tabs.activeTab.url, url, "URL of activeTab matches");
 
         return close(newWindow).then(done);
-      }).then(null, assert.fail);
+      }).catch(assert.fail);
     }
   });
 
 }
 
 // Test tab.open inNewWindow + onOpen combination
 exports.testOpenInNewWindowOnOpen = function(assert, done) {
   let startWindowCount = windows().length;
@@ -497,17 +497,17 @@ exports.testOpenInNewWindowOnOpen = func
     inNewWindow: true,
     onOpen: function(tab) {
       let newWindow = getOwnerWindow(viewFor(tab));
 
       onFocus(newWindow).then(function() {
         assert.equal(windows().length, startWindowCount + 1, "a new window was opened");
         assert.equal(getMostRecentBrowserWindow(), newWindow, "new window is active");
 
-        close(newWindow).then(done).then(null, assert.fail);
+        close(newWindow).then(done).catch(assert.fail);
       });
     }
   });
 };
 
 // TEST: onOpen event handler
 exports.testTabsEvent_onOpen = function(assert, done) {
   open().then(focus).then(window => {
@@ -520,21 +520,21 @@ exports.testTabsEvent_onOpen = function(
     };
     tabs.on('open', listener1);
 
     // add listener via collection add
     tabs.on('open', function listener2(tab) {
       assert.equal(++eventCount, 2, "both listeners notified");
       tabs.removeListener('open', listener1);
       tabs.removeListener('open', listener2);
-      close(window).then(done).then(null, assert.fail);
+      close(window).then(done).catch(assert.fail);
     });
 
     tabs.open(url);
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 };
 
 // TEST: onClose event handler
 exports.testTabsEvent_onClose = function*(assert) {
   let window = yield open().then(focus);
   let url = "data:text/html;charset=utf-8,onclose";
   let eventCount = 0;
 
@@ -616,17 +616,17 @@ exports.testTabsEvent_onCloseWindow = fu
       onClose: endTest
     });
 
     tabs.open({
       url: "data:text/html;charset=utf-8,tab4",
       onOpen: testCasePossiblyLoaded,
       onClose: endTest
     });
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 }
 
 // TEST: onReady event handler
 exports.testTabsEvent_onReady = function(assert, done) {
   open().then(focus).then(window => {
     let url = "data:text/html;charset=utf-8,onready";
     let eventCount = 0;
 
@@ -640,17 +640,17 @@ exports.testTabsEvent_onReady = function
     tabs.on('ready', function listener2(tab) {
       assert.equal(++eventCount, 2, "both listeners notified");
       tabs.removeListener('ready', listener1);
       tabs.removeListener('ready', listener2);
       close(window).then(done);
     });
 
     tabs.open(url);
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 };
 
 // TEST: onActivate event handler
 exports.testTabsEvent_onActivate = function(assert, done) {
   open().then(focus).then(window => {
     let url = "data:text/html;charset=utf-8,onactivate";
     let eventCount = 0;
 
@@ -660,21 +660,21 @@ exports.testTabsEvent_onActivate = funct
     };
     tabs.on('activate', listener1);
 
     // add listener via collection add
     tabs.on('activate', function listener2(tab) {
       assert.equal(++eventCount, 2, "both listeners notified");
       tabs.removeListener('activate', listener1);
       tabs.removeListener('activate', listener2);
-      close(window).then(done).then(null, assert.fail);
+      close(window).then(done).catch(assert.fail);
     });
 
     tabs.open(url);
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 };
 
 // onDeactivate event handler
 exports.testTabsEvent_onDeactivate = function*(assert) {
   let window = yield open().then(focus);
 
   let url = "data:text/html;charset=utf-8,ondeactivate";
   let eventCount = 0;
@@ -721,21 +721,21 @@ exports.testTabsEvent_pinning = function
       tabs.removeListener('pinned', onPinned);
       assert.ok(tab.isPinned, "notified tab is pinned");
       tab.unpin();
     });
 
     tabs.on('unpinned', function onUnpinned(tab) {
       tabs.removeListener('unpinned', onUnpinned);
       assert.ok(!tab.isPinned, "notified tab is not pinned");
-      close(window).then(done).then(null, assert.fail);
+      close(window).then(done).catch(assert.fail);
     });
 
     tabs.open(url);
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 };
 
 // TEST: per-tab event handlers
 exports.testPerTabEvents = function*(assert) {
   let window = yield open().then(focus);
   let eventCount = 0;
 
   let tab = yield new Promise(resolve => {
@@ -835,19 +835,19 @@ exports.testAttachOnMultipleDocuments = 
     });
 
     function checkEnd() {
       if (detachEventCount != 2)
         return;
 
       assert.pass("Got all detach events");
 
-      close(window).then(done).then(null, assert.fail);
+      close(window).then(done).catch(assert.fail);
     }
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 }
 
 
 exports.testAttachWrappers = function (assert, done) {
   // Check that content script has access to wrapped values by default
   open().then(focus).then(window => {
     let document = "data:text/html;charset=utf-8,<script>var globalJSVar = true; " +
                    "                       document.getElementById = 3;</script>";
@@ -861,22 +861,22 @@ exports.testAttachWrappers = function (a
                          '  self.postMessage(!("globalJSVar" in window));' +
                          '  self.postMessage(typeof window.globalJSVar == "undefined");' +
                          '} catch(e) {' +
                          '  self.postMessage(e.message);' +
                          '}',
           onMessage: function (msg) {
             assert.equal(msg, true, "Worker has wrapped objects ("+count+")");
             if (count++ == 1)
-              close(window).then(done).then(null, assert.fail);
+              close(window).then(done).catch(assert.fail);
           }
         });
       }
     });
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 }
 
 /*
 // We do not offer unwrapped access to DOM since bug 601295 landed
 // See 660780 to track progress of unwrap feature
 exports.testAttachUnwrapped = function (assert, done) {
   // Check that content script has access to unwrapped values through unsafeWindow
   openBrowserWindow(function(window, browser) {
@@ -926,34 +926,34 @@ exports['test window focus changes activ
 
           function whenReady(tab) {
             assert.pass("activate was called on windows focus change.");
             assert.equal(tab.url, url1, 'the activated tab url is correct');
 
             return close(win2).then(function() {
               assert.pass('window 2 was closed');
               return close(win1);
-            }).then(done).then(null, assert.fail);
+            }).then(done).catch(assert.fail);
           }
         });
 
         win1.focus();
       });
     }, "data:text/html;charset=utf-8,test window focus changes active tab</br><h1>Window #2");
   }, url1);
 };
 
 exports['test ready event on new window tab'] = function(assert, done) {
   let uri = encodeURI("data:text/html;charset=utf-8,Waiting for ready event!");
 
   require("sdk/tabs").on("ready", function onReady(tab) {
     if (tab.url === uri) {
       require("sdk/tabs").removeListener("ready", onReady);
       assert.pass("ready event was emitted");
-      close(window).then(done).then(null, assert.fail);
+      close(window).then(done).catch(assert.fail);
     }
   });
 
   let window = openBrowserWindow(function(){}, uri);
 };
 
 exports['test unique tab ids'] = function(assert, done) {
   var windows = require('sdk/windows').browserWindows;
--- a/addon-sdk/source/test/test-addon-window.js
+++ b/addon-sdk/source/test/test-addon-window.js
@@ -11,12 +11,12 @@ exports.testReady = function(assert, don
   let windowIsReady = false;
 
   ready.then(function() {
     assert.equal(windowIsReady, false, 'ready promise was resolved only once');
     windowIsReady = true;
 
     loader.unload();
     done();
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 }
 
 require('sdk/test').run(exports);
--- a/addon-sdk/source/test/test-child_process.js
+++ b/addon-sdk/source/test/test-child_process.js
@@ -61,17 +61,17 @@ exports.testExecOptionsEnvironment = fun
       env: { CHILD_PROCESS_ENV_TEST: 'my-value-test' }
     }, function (err, stdout, stderr) {
       assert.equal(stderr, '', 'stderr is empty');
       assert.ok(!err, 'received `cwd` option');
       assert.ok(/my-value-test/.test(stdout),
         'receives environment option');
       done();
     });
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 };
 
 exports.testExecOptionsTimeout = function (assert, done) {
   let count = 0;
   getScript('wait').then(script => {
     let child = exec(script, { timeout: 100 }, (err, stdout, stderr) => {
       assert.equal(err.killed, true, 'error has `killed` property as true');
       assert.equal(err.code, null, 'error has `code` as null');
@@ -99,29 +99,29 @@ exports.testExecOptionsTimeout = functio
     child.on('exit', exitHandler);
     child.on('close', closeHandler);
 
     function complete () {
       child.off('exit', exitHandler);
       child.off('close', closeHandler);
       done();
     }
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 };
 
 exports.testExecFileCallbackSuccess = function (assert, done) {
   getScript('args').then(script => {
     execFile(script, ['--myargs', '-j', '-s'], { cwd: PROFILE_DIR }, function (err, stdout, stderr) {
       assert.ok(!err, 'no errors found');
       assert.equal(stderr, '', 'stderr is empty');
       // Trim output since different systems have different new line output
       assert.equal(stdout.trim(), '--myargs -j -s'.trim(), 'passes in correct arguments');
       done();
     });
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 };
 
 exports.testExecFileCallbackError = function (assert, done) {
   execFile('not-real-command', { cwd: PROFILE_DIR }, function (err, stdout, stderr) {
     assert.ok(/Executable not found/.test(err.message),
       `error '${err.message}' contains error message`);
     assert.ok(err.lineNumber >= 0, 'error contains lineNumber');
     assert.ok(/resource:\/\//.test(err.fileName), 'error contains fileName');
@@ -138,17 +138,17 @@ exports.testExecFileOptionsEnvironment =
       env: { CHILD_PROCESS_ENV_TEST: 'my-value-test' }
     }, function (err, stdout, stderr) {
       assert.equal(stderr, '', 'stderr is empty');
       assert.ok(!err, 'received `cwd` option');
       assert.ok(/my-value-test/.test(stdout),
         'receives environment option');
       done();
     });
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 };
 
 exports.testExecFileOptionsTimeout = function (assert, done) {
   let count = 0;
   getScript('wait').then(script => {
     let child = execFile(script, { timeout: 100 }, (err, stdout, stderr) => {
       assert.equal(err.killed, true, 'error has `killed` property as true');
       assert.equal(err.code, null, 'error has `code` as null');
@@ -176,17 +176,17 @@ exports.testExecFileOptionsTimeout = fun
     child.on('exit', exitHandler);
     child.on('close', closeHandler);
 
     function complete () {
       child.off('exit', exitHandler);
       child.off('close', closeHandler);
       done();
     }
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 };
 
 /**
  * Not necessary to test for both `exec` and `execFile`, but
  * it is necessary to test both when the buffer is larger
  * and smaller than buffer size used by the subprocess library (1024)
  */
 exports.testExecFileOptionsMaxBufferLargeStdOut = function (assert, done) {
@@ -199,17 +199,17 @@ exports.testExecFileOptionsMaxBufferLarg
       assert.ok(/stdout maxBuffer exceeded/.test(err.toString()),
         'error contains stdout maxBuffer exceeded message');
       assert.ok(stdout.length >= 50, 'stdout has full buffer');
       assert.equal(stderr, '', 'stderr is empty');
       if (++count === 3) complete();
     });
     stdoutChild.on('exit', exitHandler);
     stdoutChild.on('close', closeHandler);
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 
   function exitHandler (code, signal) {
     assert.equal(code, null, 'Exit code is null in exit handler');
     assert.equal(signal, 'SIGTERM', 'Signal is SIGTERM in exit handler');
     if (++count === 3) complete();
   }
 
   function closeHandler (code, signal) {
@@ -234,17 +234,17 @@ exports.testExecFileOptionsMaxBufferLarg
       assert.ok(/stderr maxBuffer exceeded/.test(err.toString()),
         'error contains stderr maxBuffer exceeded message');
       assert.ok(stderr.length >= 50, 'stderr has full buffer');
       assert.equal(stdout, '', 'stdout is empty');
       if (++count === 3) complete();
     });
     stderrChild.on('exit', exitHandler);
     stderrChild.on('close', closeHandler);
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 
   function exitHandler (code, signal) {
     assert.equal(code, null, 'Exit code is null in exit handler');
     assert.equal(signal, 'SIGTERM', 'Signal is SIGTERM in exit handler');
     if (++count === 3) complete();
   }
 
   function closeHandler (code, signal) {
@@ -275,17 +275,17 @@ exports.testExecFileOptionsMaxBufferSmal
       assert.ok(/stdout maxBuffer exceeded/.test(err.toString()),
         'error contains stdout maxBuffer exceeded message');
       assert.ok(stdout.length >= 50, 'stdout has full buffer');
       assert.equal(stderr, '', 'stderr is empty');
       if (++count === 3) complete();
     });
     stdoutChild.on('exit', exitHandler);
     stdoutChild.on('close', closeHandler);
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 
   function exitHandler (code, signal) {
     // Sometimes the buffer limit is hit before the process closes successfully
     // on both OSX/Windows
     if (code === null) {
       assert.equal(code, null, 'Exit code is null in exit handler');
       assert.equal(signal, 'SIGTERM', 'Signal is SIGTERM in exit handler');
     }
@@ -326,17 +326,17 @@ exports.testExecFileOptionsMaxBufferSmal
       assert.ok(/stderr maxBuffer exceeded/.test(err.toString()),
         'error contains stderr maxBuffer exceeded message');
       assert.ok(stderr.length >= 50, 'stderr has full buffer');
       assert.equal(stdout, '', 'stdout is empty');
       if (++count === 3) complete();
     });
     stderrChild.on('exit', exitHandler);
     stderrChild.on('close', closeHandler);
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 
   function exitHandler (code, signal) {
     // Sometimes the buffer limit is hit before the process closes successfully
     // on both OSX/Windows
     if (code === null) {
       assert.equal(code, null, 'Exit code is null in exit handler');
       assert.equal(signal, 'SIGTERM', 'Signal is SIGTERM in exit handler');
     }
@@ -372,17 +372,17 @@ exports.testChildExecFileKillSignal = fu
   getScript('wait').then(script => {
     execFile(script, {
       killSignal: 'beepbeep',
       timeout: 10
     }, function (err, stdout, stderr) {
       assert.equal(err.signal, 'beepbeep', 'correctly used custom killSignal');
       done();
     });
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 };
 
 exports.testChildProperties = function (assert, done) {
   getScript('check-env').then(script => {
     let child = spawn(script, {
       env: { CHILD_PROCESS_ENV_TEST: 'my-value-test' }
     });
 
@@ -503,17 +503,17 @@ exports.testSpawnOptions = function (ass
     cwdChild = spawn(checkPwd, { cwd: PROFILE_DIR });
 
     // Do these need to be unbound?
     envChild.stdout.on('data', data => envStdout += data);
     cwdChild.stdout.on('data', data => cwdStdout += data);
 
     envChild.on('close', envClose);
     cwdChild.on('close', cwdClose);
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 
   function envClose () {
     assert.equal(envStdout.trim(), 'my-value-test', 'spawn correctly passed in ENV');
     if (++count === 2) complete();
   }
 
   function cwdClose () {
     // Check for PROFILE_DIR in the output because
--- a/addon-sdk/source/test/test-native-loader.js
+++ b/addon-sdk/source/test/test-native-loader.js
@@ -232,17 +232,17 @@ for (let variant of variants) {
         manifest: manifest,
         isNative: true
       });
 
       let program = main(loader);
       testLoader(program, assert);
       unload(loader);
       done();
-    }).then(null, (reason) => console.error(reason));
+    }).catch((reason) => console.error(reason));
   };
 
   exports[`test require#resolve with relative, dependencies (${variant.description})`] = function(assert, done) {
     getJSON('/fixtures/native-addon-test/package.json').then(manifest => {
       let rootURI = variant.getRootURI('native-addon-test');
       let loader = Loader({
         paths: makePaths(rootURI),
         rootURI: rootURI,
@@ -260,17 +260,17 @@ for (let variant of variants) {
       assert.equal(program.require.resolve("modules/Promise.jsm"), "resource://gre/modules/Promise.jsm", "works with path lookups");
 
       // TODO bug 1050422, handle loading non JS/JSM file paths
       // assert.equal(program.require.resolve("test-assets/styles.css"), fixtureRoot + "node_modules/test-assets/styles.css",
       // "works with different file extension lookups in dependencies");
 
       unload(loader);
       done();
-    }).then(null, (reason) => console.error(reason));
+    }).catch((reason) => console.error(reason));
   };
 }
 
 before(exports, () => {
   for (let fixture of fixtures) {
     let url = `jar:${root}/fixtures/${fixture}.xpi!/`;
 
     resProto.setSubstitution(fixture, NetUtil.newURI(url));
@@ -304,17 +304,17 @@ exports['test JSM loading'] = function (
       program.isLoadedAbsolute(20),
       program.isLoadedJSAbsolute(30)
     ]).then(([path, absolute, jsabsolute]) => {
       assert.equal(path, 10, 'JSM files resolved from path work');
       assert.equal(absolute, 20, 'JSM files resolved from full resource:// work');
       assert.equal(jsabsolute, 30, 'JS files resolved from full resource:// work');
     }).then(done, console.error);
 
-  }).then(null, console.error);
+  }).catch(console.error);
 };
 
 function testLoader (program, assert) {
   // Test 'main' entries
   // no relative custom main `lib/index.js`
   assert.equal(program.customMainModule, 'custom entry file',
     'a node_module dependency correctly uses its `main` entry in manifest');
   // relative custom main `./lib/index.js`
@@ -383,12 +383,12 @@ function loadAddon (uri, map) {
       rootURI: rootURI,
       manifest: manifest,
       isNative: true,
       modules: {
         '@test/options': testOptions
       }
     });
     let program = main(loader);
-  }).then(null, console.error);
+  }).catch(console.error);
 }
 
 require('sdk/test').run(exports);
--- a/addon-sdk/source/test/test-panel.js
+++ b/addon-sdk/source/test/test-panel.js
@@ -1016,17 +1016,17 @@ exports['test panel CSS'] = function(ass
       assert.equal(div.offsetHeight, 120,
         "Panel contentStyleFile worked");
 
       assert.equal(window.getComputedStyle(div).borderTopStyle, "dashed",
         "Panel contentStyleFile with relative path worked");
 
         loader.unload();
         done();
-      }).then(null, assert.fail);
+      }).catch(assert.fail);
     }
   });
 
   panel.show();
 };
 
 exports['test panel contentScriptFile'] = function(assert, done) {
   const { merge } = require("sdk/util/object");
--- a/addon-sdk/source/test/test-promise.js
+++ b/addon-sdk/source/test/test-promise.js
@@ -112,22 +112,22 @@ exports['test error recovery with promis
     let deferred = defer();
     deferred.resolve('recovery');
     return deferred.promise;
   }).then(function(actual) {
     assert.equal(actual, 'recovery', 'recorvered via promise');
     let deferred = defer();
     deferred.reject('error');
     return deferred.promise;
-  }).then(null, function(actual) {
+  }).catch(function(actual) {
     assert.equal(actual, 'error', 'rejected via promise');
     let deferred = defer();
     deferred.reject('end');
     return deferred.promise;
-  }).then(null, function(actual) {
+  }).catch(function(actual) {
     assert.equal(actual, 'end', 'rejeced via promise');
     done();
   });
 
   deferred.reject('reason');
 };
 
 exports['test propagation'] = function(assert, done) {
@@ -145,27 +145,27 @@ exports['test propagation'] = function(a
 
 exports['test chaining'] = function(assert, done) {
   let boom = Error('boom'), brax = Error('braxXXx');
   let deferred = defer();
 
   deferred.promise.then().then().then(function(actual) {
     assert.equal(actual, 2, 'value propagates unchanged');
     return actual + 2;
-  }).then(null, function(reason) {
+  }).catch(function(reason) {
     assert.fail('should not reject');
   }).then(function(actual) {
     assert.equal(actual, 4, 'value propagates through if not handled');
     throw boom;
   }).then(function(actual) {
     assert.fail('exception must reject promise');
-  }).then().then(null, function(actual) {
+  }).then().catch(function(actual) {
     assert.equal(actual, boom, 'reason propagates unchanged');
     throw brax;
-  }).then().then(null, function(actual) {
+  }).then().catch(function(actual) {
     assert.equal(actual, brax, 'reason changed becase of exception');
     return 'recovery';
   }).then(function(actual) {
     assert.equal(actual, 'recovery', 'recovered from error');
     done();
   });
 
   deferred.resolve(2);
@@ -236,17 +236,17 @@ exports['test promised error handling'] 
 exports['test errors in promise resolution handlers are propagated'] = function(assert, done) {
   var expected = Error('Boom');
   var { promise, resolve } = defer();
 
   promise.then(function() {
     throw expected;
   }).then(function() {
     return undefined;
-  }).then(null, function(actual) {
+  }).catch(function(actual) {
     assert.equal(actual, expected, 'rejected as expected');
   }).then(done, assert.fail);
 
   resolve({});
 };
 
 exports['test return promise form promised'] = function(assert, done) {
   let f = promised(function() {
@@ -440,17 +440,17 @@ function testEnvironment ({all, resolve,
   all([resolve(5), resolve(10), 925]).then(val => {
     assert.equal(val[0], 5, 'promise#all works ' + type);
     assert.equal(val[1], 10, 'promise#all works ' + type);
     assert.equal(val[2], 925, 'promise#all works ' + type);
     return resolve(1000);
   }).then(value => {
     assert.equal(value, 1000, 'promise#resolve works ' + type);
     return reject('testing reject');
-  }).then(null, reason => {
+  }).catch(reason => {
     assert.equal(reason, 'testing reject', 'promise#reject works ' + type);
     let deferred = defer();
     setTimeout(() => deferred.resolve('\\m/'), 10);
     return deferred.promise;
   }).then(value => {
     assert.equal(value, '\\m/', 'promise#defer works ' + type);
     return promised(x => x * x)(5);
   }).then(value => {
--- a/addon-sdk/source/test/test-ui-toggle-button.js
+++ b/addon-sdk/source/test/test-ui-toggle-button.js
@@ -1200,17 +1200,17 @@ exports['test button checked'] = functio
           'clicked:foo', 'changed:foo:false', 'clicked:foo', 'changed:foo:true'
         ],
         'button change events works');
 
       close(window).
         then(loader.unload).
         then(done, assert.fail);
     })
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 }
 
 exports['test button is checked on window level'] = function(assert, done) {
   let loader = Loader(module);
   let { ToggleButton } = loader.require('sdk/ui');
   let { browserWindows } = loader.require('sdk/windows');
   let tabs = loader.require('sdk/tabs');
 
@@ -1262,17 +1262,17 @@ exports['test button is checked on windo
           'window state, checked is `false`.');
 
         tab.close(()=> {
           close(window).
             then(loader.unload).
             then(done, assert.fail);
         })
       }).
-      then(null, assert.fail);
+      catch(assert.fail);
     }
   });
 
 };
 
 exports['test button click do not messing up states'] = function(assert) {
   let loader = Loader(module);
   let { ToggleButton } = loader.require('sdk/ui');
--- a/addon-sdk/source/test/test-window-utils-private-browsing.js
+++ b/addon-sdk/source/test/test-window-utils-private-browsing.js
@@ -74,17 +74,17 @@ exports.testWindowTrackerIgnoresPrivateW
 
     return close(window).then(function() {
       return makeEmptyBrowserWindow().then(function(window) {
         myNonPrivateWindow = window;
         assert.pass('opened new window');
         return close(window);
       });
     });
-  }).then(null, assert.fail);
+  }).catch(assert.fail);
 };
 
 // Test setting activeWIndow and onFocus for private windows
 exports.testSettingActiveWindowDoesNotIgnorePrivateWindow = function(assert, done) {
   let browserWindow = WM.getMostRecentWindow("navigator:browser");
 
   assert.equal(windowUtils.activeBrowserWindow, browserWindow,
                "Browser window is the active browser window.");
@@ -137,17 +137,17 @@ exports.testSettingActiveWindowDoesNotIg
     }).then(_ => {
       assert.strictEqual(windowUtils.activeBrowserWindow, browserWindow,
                          "Correct active browser window when pb mode is supported [4]");
       assert.strictEqual(windowUtils.activeWindow, browserWindow,
                          "Correct active window when pb mode is supported [4]");
 
       return close(window);
     })
-  }).then(done).then(null, assert.fail);
+  }).then(done).catch(assert.fail);
 };
 
 exports.testActiveWindowDoesNotIgnorePrivateWindow = function(assert, done) {
   // make a new private window
   makeEmptyBrowserWindow({
     private: true
   }).then(function(window) {
     // PWPB case
@@ -177,17 +177,17 @@ exports.testActiveWindowDoesNotIgnorePri
                    "active window is not private");
       assert.equal(isPrivate(windowUtils.activeBrowserWindow), false,
                    "active browser window is not private");
       assert.equal(isWindowPrivate(window), false, "window is not private");
       assert.equal(isPrivate(window), false, "window is not private");
     }
 
     return close(window);
-  }).then(done).then(null, assert.fail);
+  }).then(done).catch(assert.fail);
 }
 
 exports.testWindowIteratorIgnoresPrivateWindows = function(assert, done) {
   // make a new private window
   makeEmptyBrowserWindow({
     private: true
   }).then(function(window) {
     // PWPB case
@@ -199,12 +199,12 @@ exports.testWindowIteratorIgnoresPrivate
     // Global case
     else {
       assert.equal(isWindowPrivate(window), false, "window is not private");
       assert.ok(toArray(windowUtils.windowIterator()).indexOf(window) > -1,
                 "window is in windowIterator()");
     }
 
     return close(window);
-  }).then(done).then(null, assert.fail);
+  }).then(done).catch(assert.fail);
 };
 
 require("sdk/test").run(exports);
--- a/browser/base/content/aboutaccounts/aboutaccounts.js
+++ b/browser/base/content/aboutaccounts/aboutaccounts.js
@@ -440,31 +440,31 @@ function migrateToDevEdition(urlParams) 
     let accountData = JSON.parse(text).accountData;
     updateDisplayedEmail(accountData);
     return fxAccounts.setSignedInUser(accountData);
   }).then(() => {
     return fxAccounts.promiseAccountsForceSigninURI().then(url => {
       show("remote");
       wrapper.init(url, urlParams);
     });
-  }).then(null, error => {
+  }).catch(error => {
     log("Failed to migrate FX Account: " + error);
     show("stage", "intro");
     // load the remote frame in the background
     fxAccounts.promiseAccountsSignUpURI().then(uri => {
       wrapper.init(uri, urlParams)
     }).catch(e => {
       console.log("Failed to load signup page", e);
       setErrorPage("configError");
     });
   }).then(() => {
     // Reset the pref after migration.
     Services.prefs.setBoolPref("identity.fxaccounts.migrateToDevEdition", false);
     return true;
-  }).then(null, err => {
+  }).catch(err => {
     Cu.reportError("Failed to reset the migrateToDevEdition pref: " + err);
     return false;
   });
 }
 
 // Helper function that returns the path of the default profile on disk. Will be
 // overridden in tests.
 function getDefaultProfilePath() {
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1669,17 +1669,17 @@ var gBrowserInit = {
       Cu.reportError("Could not end startup crash tracking: " + ex);
     }
 
     // Delay this a minute into the idle time because there's no rush.
     requestIdleCallback(() => {
       this.gmpInstallManager = new GMPInstallManager();
       // We don't really care about the results, if someone is interested they
       // can check the log.
-      this.gmpInstallManager.simpleCheckAndInstall().then(null, () => {});
+      this.gmpInstallManager.simpleCheckAndInstall().catch(() => {});
     }, {timeout: 1000 * 60});
 
     SessionStore.promiseInitialized.then(() => {
       // Bail out if the window has been closed in the meantime.
       if (window.closed) {
         return;
       }
 
--- a/browser/base/content/sanitizeDialog.js
+++ b/browser/base/content/sanitizeDialog.js
@@ -98,19 +98,19 @@ var gSanitizePromptDialog = {
     let docElt = document.documentElement;
     let acceptButton = docElt.getButton("accept");
     acceptButton.disabled = true;
     acceptButton.setAttribute("label",
                               this.bundleBrowser.getString("sanitizeButtonClearing"));
     docElt.getButton("cancel").disabled = true;
 
     try {
-      s.sanitize().then(null, Components.utils.reportError)
+      s.sanitize().catch(Components.utils.reportError)
                   .then(() => window.close())
-                  .then(null, Components.utils.reportError);
+                  .catch(Components.utils.reportError);
       return false;
     } catch (er) {
       Components.utils.reportError("Exception during sanitize: " + er);
       return true; // We *do* want to close immediately on error.
     }
   },
 
   /**
--- a/browser/components/customizableui/CustomizeMode.jsm
+++ b/browser/components/customizableui/CustomizeMode.jsm
@@ -421,17 +421,17 @@ CustomizeMode.prototype = {
           this.panelUIContents.setAttribute("showoutline", "true");
         }
         delete this._enableOutlinesTimeout;
       }, 0);
 
       if (!this._wantToBeInCustomizeMode) {
         this.exit();
       }
-    })().then(null, e => {
+    })().catch(e => {
       log.error("Error entering customize mode", e);
       // We should ensure this has been called, and calling it again doesn't hurt:
       window.PanelUI.endBatchUpdate();
       this._handler.isEnteringCustomizeMode = false;
       // Exit customize mode to ensure proper clean-up when entering failed.
       this.exit();
     });
   },
@@ -591,17 +591,17 @@ CustomizeMode.prototype = {
       this._transitioning = false;
       this._handler.isExitingCustomizeMode = false;
       CustomizableUI.dispatchToolboxEvent("aftercustomization", {}, window);
       CustomizableUI.notifyEndCustomizing(window);
 
       if (this._wantToBeInCustomizeMode) {
         this.enter();
       }
-    })().then(null, e => {
+    })().catch(e => {
       log.error("Error exiting customize mode", e);
       if (!gPhotonStructure) {
         // We should ensure this has been called, and calling it again doesn't hurt:
         window.PanelUI.endBatchUpdate();
       }
       this._handler.isExitingCustomizeMode = false;
     });
   },
@@ -861,17 +861,17 @@ CustomizeMode.prototype = {
         } else if (provider == CustomizableUI.PROVIDER_SPECIAL) {
           this.visiblePalette.removeChild(paletteChild);
         }
 
         paletteChild = nextChild;
       }
       this.visiblePalette.hidden = false;
       this.window.gNavToolbox.palette = this._stowedPalette;
-    })().then(null, log.error);
+    })().catch(log.error);
   },
 
   isCustomizableItem(aNode) {
     return aNode.localName == "toolbarbutton" ||
            aNode.localName == "toolbaritem" ||
            aNode.localName == "toolbarseparator" ||
            aNode.localName == "toolbarspring" ||
            aNode.localName == "toolbarspacer";
@@ -1067,17 +1067,17 @@ CustomizeMode.prototype = {
     let target = CustomizableUI.getCustomizeTargetForArea(aArea, this.window);
     if (!target || this.areas.has(target)) {
       return null;
     }
 
     this._addDragHandlers(target);
     for (let child of target.children) {
       if (this.isCustomizableItem(child) && !this.isWrappedToolbarItem(child)) {
-        await this.deferredWrapToolbarItem(child, CustomizableUI.getPlaceForItem(child)).then(null, log.error);
+        await this.deferredWrapToolbarItem(child, CustomizableUI.getPlaceForItem(child)).catch(log.error);
       }
     }
     this.areas.add(target);
     return target;
   },
 
   _wrapToolbarItemSync(aArea) {
     let target = CustomizableUI.getCustomizeTargetForArea(aArea, this.window);
@@ -1144,17 +1144,17 @@ CustomizeMode.prototype = {
         for (let toolbarItem of target.children) {
           if (this.isWrappedToolbarItem(toolbarItem)) {
             await this.deferredUnwrapToolbarItem(toolbarItem);
           }
         }
         this._removeDragHandlers(target);
       }
       this.areas.clear();
-    })().then(null, log.error);
+    })().catch(log.error);
   },
 
   _removeExtraToolbarsIfEmpty() {
     let toolbox = this.window.gNavToolbox;
     for (let child of toolbox.children) {
       if (child.hasAttribute("customindex")) {
         let placements = CustomizableUI.getWidgetIdsInArea(child.id);
         if (!placements.length) {
@@ -1200,17 +1200,17 @@ CustomizeMode.prototype = {
       this._updateResetButton();
       this._updateUndoResetButton();
       this._updateEmptyPaletteNotice();
       this._showPanelCustomizationPlaceholders();
       this.resetting = false;
       if (!this._wantToBeInCustomizeMode) {
         this.exit();
       }
-    })().then(null, log.error);
+    })().catch(log.error);
   },
 
   undoReset() {
     this.resetting = true;
 
     return (async () => {
       this._removePanelCustomizationPlaceholders();
       await this.depopulatePalette();
@@ -1224,17 +1224,17 @@ CustomizeMode.prototype = {
       this.populatePalette();
 
       this.persistCurrentSets(true);
 
       this._updateResetButton();
       this._updateUndoResetButton();
       this._updateEmptyPaletteNotice();
       this.resetting = false;
-    })().then(null, log.error);
+    })().catch(log.error);
   },
 
   _onToolbarVisibilityChange(aEvent) {
     let toolbar = aEvent.target;
     if (aEvent.detail.visible && toolbar.getAttribute("customizable") == "true") {
       toolbar.setAttribute("customizing", "true");
     } else {
       toolbar.removeAttribute("customizing");
--- a/browser/components/customizableui/content/panelUI.js
+++ b/browser/components/customizableui/content/panelUI.js
@@ -439,17 +439,17 @@ const PanelUI = {
           CustomizableUI.registerMenuPanel(this.contents, CustomizableUI.AREA_PANEL);
         } finally {
           this.endBatchUpdate();
         }
       }
       this._updateQuitTooltip();
       this.panel.hidden = false;
       this._isReady = true;
-    })().then(null, Cu.reportError);
+    })().catch(Cu.reportError);
 
     return this._readyPromise;
   },
 
   /**
    * Switch the panel to the main view if it's not already
    * in that view.
    */
--- a/browser/components/downloads/DownloadsCommon.jsm
+++ b/browser/components/downloads/DownloadsCommon.jsm
@@ -462,17 +462,17 @@ this.DownloadsCommon = {
         aFile.launch();
       } catch (ex) {
         // If launch fails, try sending it through the system's external "file:"
         // URL handler.
         Cc["@mozilla.org/uriloader/external-protocol-service;1"]
           .getService(Ci.nsIExternalProtocolService)
           .loadUrl(NetUtil.newURI(aFile));
       }
-    }).then(null, Cu.reportError);
+    }).catch(Cu.reportError);
   },
 
   /**
    * Show a downloaded file in the system file manager.
    *
    * @param aFile
    *        a downloaded file.
    */
@@ -669,17 +669,17 @@ function DownloadsDataCtor(aPrivate) {
 DownloadsDataCtor.prototype = {
   /**
    * Starts receiving events for current downloads.
    */
   initializeDataLink() {
     if (!this._dataLinkInitialized) {
       let promiseList = Downloads.getList(this._isPrivate ? Downloads.PRIVATE
                                                           : Downloads.PUBLIC);
-      promiseList.then(list => list.addView(this)).then(null, Cu.reportError);
+      promiseList.then(list => list.addView(this)).catch(Cu.reportError);
       this._dataLinkInitialized = true;
     }
   },
   _dataLinkInitialized: false,
 
   /**
    * Iterator for all the available Download objects. This is empty until the
    * data has been loaded using the JavaScript API for downloads.
@@ -703,17 +703,17 @@ DownloadsDataCtor.prototype = {
 
   /**
    * Asks the back-end to remove finished downloads from the list.
    */
   removeFinished() {
     let promiseList = Downloads.getList(this._isPrivate ? Downloads.PRIVATE
                                                         : Downloads.PUBLIC);
     promiseList.then(list => list.removeFinished())
-               .then(null, Cu.reportError);
+               .catch(Cu.reportError);
     let indicatorData = this._isPrivate ? PrivateDownloadsIndicatorData
                                         : DownloadsIndicatorData;
     indicatorData.attention = DownloadsCommon.ATTENTION_NONE;
   },
 
   // Integration with the asynchronous Downloads back-end
 
   onDownloadAdded(download) {
--- a/browser/components/downloads/DownloadsTaskbar.jsm
+++ b/browser/components/downloads/DownloadsTaskbar.jsm
@@ -105,17 +105,17 @@ this.DownloadsTaskbar = {
       Downloads.getSummary(Downloads.ALL).then(summary => {
         // In case the method is re-entered, we simply ignore redundant
         // invocations of the callback, instead of keeping separate state.
         if (this._summary) {
           return undefined;
         }
         this._summary = summary;
         return this._summary.addView(this);
-      }).then(null, Cu.reportError);
+      }).catch(Cu.reportError);
     }
   },
 
   /**
    * On Windows, attaches the taskbar indicator to the specified browser window.
    */
   _attachIndicator(aWindow) {
     // Activate the indicator on the specified window.
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1211,17 +1211,17 @@ BrowserGlue.prototype = {
       }
       if (newProfile) {
         // We don't want a default profile with Developer Edition settings, an
         // empty profile directory will do. The profile service of the other
         // Firefox will populate it with its own stuff.
         let newProfilePath = newProfile.rootDir.path;
         OS.File.removeDir(newProfilePath).then(() => {
           return OS.File.makeDir(newProfilePath);
-        }).then(null, e => {
+        }).catch(e => {
           Cu.reportError("Could not empty profile 'default': " + e);
         });
       }
     }
   },
 
   _onQuitRequest: function BG__onQuitRequest(aCancelQuit, aQuitType) {
     // If user has already dismissed quit request, then do nothing
--- a/browser/components/places/content/browserPlacesViews.js
+++ b/browser/components/places/content/browserPlacesViews.js
@@ -1637,17 +1637,17 @@ PlacesToolbar.prototype = {
   },
 
   _onDrop: function PT__onDrop(aEvent) {
     PlacesControllerDragHelper.currentDropTarget = aEvent.target;
 
     let dropPoint = this._getDropPoint(aEvent);
     if (dropPoint && dropPoint.ip) {
       PlacesControllerDragHelper.onDrop(dropPoint.ip, aEvent.dataTransfer)
-                                .then(null, Components.utils.reportError);
+                                .catch(Components.utils.reportError);
       aEvent.preventDefault();
     }
 
     this._cleanupDragDetails();
     aEvent.stopPropagation();
   },
 
   _onDragExit: function PT__onDragExit(aEvent) {
--- a/browser/components/places/content/controller.js
+++ b/browser/components/places/content/controller.js
@@ -212,40 +212,40 @@ PlacesController.prototype = {
 
   doCommand: function PC_doCommand(aCommand) {
     switch (aCommand) {
     case "cmd_undo":
       if (!PlacesUIUtils.useAsyncTransactions) {
         PlacesUtils.transactionManager.undoTransaction();
         return;
       }
-      PlacesTransactions.undo().then(null, Components.utils.reportError);
+      PlacesTransactions.undo().catch(Components.utils.reportError);
       break;
     case "cmd_redo":
       if (!PlacesUIUtils.useAsyncTransactions) {
         PlacesUtils.transactionManager.redoTransaction();
         return;
       }
-      PlacesTransactions.redo().then(null, Components.utils.reportError);
+      PlacesTransactions.redo().catch(Components.utils.reportError);
       break;
     case "cmd_cut":
     case "placesCmd_cut":
       this.cut();
       break;
     case "cmd_copy":
     case "placesCmd_copy":
       this.copy();
       break;
     case "cmd_paste":
     case "placesCmd_paste":
-      this.paste().then(null, Components.utils.reportError);
+      this.paste().catch(Components.utils.reportError);
       break;
     case "cmd_delete":
     case "placesCmd_delete":
-      this.remove("Remove Selection").then(null, Components.utils.reportError);
+      this.remove("Remove Selection").catch(Components.utils.reportError);
       break;
     case "placesCmd_deleteDataHost":
       var host;
       if (PlacesUtils.nodeIsHost(this._view.selectedNode)) {
         var queries = this._view.selectedNode.getQueries();
         host = queries[0].domain;
       } else
         host = NetUtil.newURI(this._view.selectedNode.uri).host;
@@ -281,17 +281,17 @@ PlacesController.prototype = {
       break;
     case "placesCmd_moveBookmarks":
       this.moveSelectedBookmarks();
       break;
     case "placesCmd_reload":
       this.reloadSelectedLivemark();
       break;
     case "placesCmd_sortBy:name":
-      this.sortFolderByName().then(null, Components.utils.reportError);
+      this.sortFolderByName().catch(Components.utils.reportError);
       break;
     case "placesCmd_createBookmark":
       let node = this._view.selectedNode;
       PlacesUIUtils.showBookmarkDialog({ action: "add",
                                          type: "bookmark",
                                          hiddenRows: [ "description",
                                                         "keyword",
                                                         "location",
--- a/browser/components/places/content/menu.xml
+++ b/browser/components/places/content/menu.xml
@@ -358,17 +358,17 @@
       ]]></handler>
 
       <handler event="drop"><![CDATA[
         PlacesControllerDragHelper.currentDropTarget = event.target;
 
         let dropPoint = this._getDropPoint(event);
         if (dropPoint && dropPoint.ip) {
           PlacesControllerDragHelper.onDrop(dropPoint.ip, event.dataTransfer)
-                                    .then(null, Components.utils.reportError);
+                                    .catch(Components.utils.reportError);
           event.preventDefault();
         }
 
         this._cleanupDragDetails();
         event.stopPropagation();
       ]]></handler>
 
       <handler event="dragover"><![CDATA[
--- a/browser/components/places/content/moveBookmarks.js
+++ b/browser/components/places/content/moveBookmarks.js
@@ -49,17 +49,17 @@ var gMoveBookmarksDialog = {
       let newParentGuid = await PlacesUtils.promiseItemGuid(selectedFolderId);
       for (let node of this._nodes) {
         // Nothing to do if the node is already under the selected folder.
         if (node.parent.itemId == selectedFolderId)
           continue;
         await PlacesTransactions.Move({ guid: node.bookmarkGuid,
                                         newParentGuid }).transact();
       }
-    }).then(null, Components.utils.reportError);
+    }).catch(Components.utils.reportError);
   },
 
   newFolder: function MBD_newFolder() {
     // The command is disabled when the tree is not focused
     this.foldersTree.focus();
     goDoCommand("placesCmd_new:folder");
   }
 };
--- a/browser/components/places/content/places.js
+++ b/browser/components/places/content/places.js
@@ -369,17 +369,17 @@ var PlacesOrganizer = {
    * Open a file-picker and import the selected file into the bookmarks store
    */
   importFromFile: function PO_importFromFile() {
     let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
     let fpCallback = function fpCallback_done(aResult) {
       if (aResult != Ci.nsIFilePicker.returnCancel && fp.fileURL) {
         Components.utils.import("resource://gre/modules/BookmarkHTMLUtils.jsm");
         BookmarkHTMLUtils.importFromURL(fp.fileURL.spec, false)
-                         .then(null, Components.utils.reportError);
+                         .catch(Components.utils.reportError);
       }
     };
 
     fp.init(window, PlacesUIUtils.getString("SelectImport"),
             Ci.nsIFilePicker.modeOpen);
     fp.appendFilters(Ci.nsIFilePicker.filterHTML);
     fp.open(fpCallback);
   },
@@ -388,17 +388,17 @@ var PlacesOrganizer = {
    * Allows simple exporting of bookmarks.
    */
   exportBookmarks: function PO_exportBookmarks() {
     let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
     let fpCallback = function fpCallback_done(aResult) {
       if (aResult != Ci.nsIFilePicker.returnCancel) {
         Components.utils.import("resource://gre/modules/BookmarkHTMLUtils.jsm");
         BookmarkHTMLUtils.exportToFile(fp.file.path)
-                         .then(null, Components.utils.reportError);
+                         .catch(Components.utils.reportError);
       }
     };
 
     fp.init(window, PlacesUIUtils.getString("EnterExport"),
             Ci.nsIFilePicker.modeSave);
     fp.appendFilters(Ci.nsIFilePicker.filterHTML);
     fp.defaultString = "bookmarks.html";
     fp.open(fpCallback);
--- a/browser/components/places/content/treeView.js
+++ b/browser/components/places/content/treeView.js
@@ -1352,17 +1352,17 @@ PlacesTreeView.prototype = {
 
   drop: function PTV_drop(aRow, aOrientation, aDataTransfer) {
     // We are responsible for translating the |index| and |orientation|
     // parameters into a container id and index within the container,
     // since this information is specific to the tree view.
     let ip = this._getInsertionPoint(aRow, aOrientation);
     if (ip) {
       PlacesControllerDragHelper.onDrop(ip, aDataTransfer)
-                                .then(null, Components.utils.reportError);
+                                .catch(Components.utils.reportError);
     }
 
     PlacesControllerDragHelper.currentDropTarget = null;
   },
 
   getParentIndex: function PTV_getParentIndex(aRow) {
     let [, parentRow] = this._getParentByChildRow(aRow);
     return parentRow;
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadLastDir_c.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadLastDir_c.js
@@ -73,17 +73,17 @@ function test() {
          "LastDir should be the expected last dir");
       // gDownloadLastDir should be usable outside of private windows
       is(gDownloadLastDir.file.path, aGlobalLastDir.path,
          "gDownloadLastDir should be the expected global last dir");
 
       gDownloadLastDir.cleanupPrivateFile();
       aWin.close();
       aCallback();
-    }).then(null, function() { ok(false); });
+    }).catch(function() { ok(false); });
   }
 
   testOnWindow(false, function(win, downloadDir) {
     testDownloadDir(win, downloadDir, file1, tmpDir, dir1, dir1, function() {
       testOnWindow(true, function(win1, downloadDir1) {
         testDownloadDir(win1, downloadDir1, file2, dir1, dir1, dir2, function() {
           testOnWindow(false, function(win2, downloadDir2) {
             testDownloadDir(win2, downloadDir2, file3, dir1, dir3, dir3, finish);
--- a/browser/components/uitour/UITour.jsm
+++ b/browser/components/uitour/UITour.jsm
@@ -648,17 +648,17 @@ this.UITour = {
             let onPopupShown = () => {
               searchbar.textbox.popup.removeEventListener("popupshown", onPopupShown);
               this.sendPageCallback(messageManager, data.callbackID);
             };
 
             searchbar.textbox.popup.addEventListener("popupshown", onPopupShown);
             searchbar.openSuggestionsPanel();
           }
-        }).then(null, Cu.reportError);
+        }).catch(Cu.reportError);
         break;
       }
 
       case "ping": {
         if (typeof data.callbackID == "string")
           this.sendPageCallback(messageManager, data.callbackID);
         break;
       }
--- a/browser/components/uitour/test/browser_UITour.js
+++ b/browser/components/uitour/test/browser_UITour.js
@@ -154,17 +154,17 @@ var tests = [
         gContentAPI.showHighlight("appMenu");
         waitForElementToBeVisible(highlight, function() {
           isnot(PanelUI.panel.state, "closed",
                 "Panel should remain open since UITour didn't open it in the first place");
           gContentAPI.hideMenu("appMenu");
           done();
         }, "Highlight should move to the appMenu button");
       }, "Highlight should be shown after showHighlight() for fixed panel items");
-    }).then(null, Components.utils.reportError);
+    }).catch(Components.utils.reportError);
   },
   function test_highlight_effect(done) {
     function waitForHighlightWithEffect(highlightEl, effect, next, error) {
       return waitForCondition(() => highlightEl.getAttribute("active") == effect,
                               next,
                               error);
     }
     function checkDefaultEffect() {
--- a/browser/components/uitour/test/browser_UITour2.js
+++ b/browser/components/uitour/test/browser_UITour2.js
@@ -58,17 +58,17 @@ var tests = [
                 ok(!PanelUI.panel.hasAttribute("noautohide"), "@noautohide on the menu panel should have been cleaned up on close");
                 done();
               });
               gContentAPI.hideMenu("appMenu");
             }, "Info should move to the appMenu button");
           });
         }, "Info should be shown after showInfo() for fixed menu panel items");
       });
-    }).then(null, Components.utils.reportError);
+    }).catch(Components.utils.reportError);
   },
   taskify(async function test_bookmarks_menu() {
     let bookmarksMenuButton = document.getElementById("bookmarks-menu-button");
 
     is(bookmarksMenuButton.open, false, "Menu should initially be closed");
     gContentAPI.showMenu("bookmarks");
 
     await waitForConditionPromise(() => {
--- a/browser/experiments/test/addons/experiment-racybranch/bootstrap.js
+++ b/browser/experiments/test/addons/experiment-racybranch/bootstrap.js
@@ -21,14 +21,14 @@ function realstartup() {
   let experiment = experiments._getActiveExperiment();
   if (experiment.branch) {
     Cu.reportError("Found pre-existing branch: " + experiment.branch);
     return;
   }
 
   let branch = "racy-set";
   experiments.setExperimentBranch(experiment.id, branch)
-    .then(null, Cu.reportError);
+    .catch(Cu.reportError);
 }
 
 function shutdown() { }
 function install() { }
 function uninstall() { }
--- a/browser/modules/AboutHome.jsm
+++ b/browser/modules/AboutHome.jsm
@@ -182,14 +182,14 @@ var AboutHome = {
       }
 
       if (target && target.messageManager) {
         target.messageManager.sendAsyncMessage("AboutHome:Update", data);
       } else {
         let mm = Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIMessageListenerManager);
         mm.broadcastAsyncMessage("AboutHome:Update", data);
       }
-    }).then(null, function onError(x) {
+    }).catch(function onError(x) {
       Cu.reportError("Error in AboutHome.sendAboutHomeData: " + x);
     });
   },
 
 };
--- a/devtools/client/canvasdebugger/panel.js
+++ b/devtools/client/canvasdebugger/panel.js
@@ -45,17 +45,17 @@ CanvasDebuggerPanel.prototype = {
         this.panelWin.gFront = new CanvasFront(this.target.client, this.target.form);
         return this.panelWin.startupCanvasDebugger();
       })
       .then(() => {
         this.isReady = true;
         this.emit("ready");
         return this;
       })
-      .then(null, function onError(aReason) {
+      .catch(function onError(aReason) {
         DevToolsUtils.reportException("CanvasDebuggerPanel.prototype.open", aReason);
       });
   },
 
   // DevToolPanel API
 
   get target() {
     return this._toolbox.target;
--- a/devtools/client/canvasdebugger/test/head.js
+++ b/devtools/client/canvasdebugger/test/head.js
@@ -121,17 +121,17 @@ function ifTestingSupported() {
 
 function ifTestingUnsupported() {
   todo(false, "Skipping test because some required functionality isn't supported.");
   finish();
 }
 
 function test() {
   let generator = isTestingSupported() ? ifTestingSupported : ifTestingUnsupported;
-  Task.spawn(generator).then(null, handleError);
+  Task.spawn(generator).catch(handleError);
 }
 
 function createCanvas() {
   return document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
 }
 
 function isTestingSupported() {
   if (!gRequiresWebGL) {
--- a/devtools/client/commandline/test/helpers.js
+++ b/devtools/client/commandline/test/helpers.js
@@ -129,17 +129,17 @@ var { helpers, assert } = (function () {
     options.tab = tabbrowser.addTab();
     tabbrowser.selectedTab = options.tab;
     options.browser = tabbrowser.getBrowserForTab(options.tab);
     options.target = TargetFactory.forTab(options.tab);
 
     var loaded = helpers.listenOnce(options.browser, "load", true).then(function (ev) {
       var reply = callback.call(null, options);
 
-      return Promise.resolve(reply).then(null, function (error) {
+      return Promise.resolve(reply).catch(function (error) {
         ok(false, error);
       }).then(function () {
         tabbrowser.removeTab(options.tab);
 
         delete options.target;
         delete options.browser;
         delete options.tab;
 
@@ -325,17 +325,17 @@ var { helpers, assert } = (function () {
 
       return win.DeveloperToolbar.show(true).then(function () {
         var toolbar = win.DeveloperToolbar;
         innerOptions.automator = createDeveloperToolbarAutomator(toolbar);
         innerOptions.requisition = toolbar.requisition;
 
         var reply = callback.call(null, innerOptions);
 
-        return Promise.resolve(reply).then(null, function (error) {
+        return Promise.resolve(reply).catch(function (error) {
           ok(false, error);
           console.error(error);
         }).then(function () {
           win.DeveloperToolbar.hide().then(function () {
             delete innerOptions.automator;
           });
         });
       });
--- a/devtools/client/debugger/panel.js
+++ b/devtools/client/debugger/panel.js
@@ -64,17 +64,17 @@ DebuggerPanel.prototype = {
 
           let keyShortcut = this.translateToKeyShortcut(keycode, modifiers);
           this._toolbox.useKeyWithSplitConsole(keyShortcut, handler, "jsdebugger");
         }
         this.isReady = true;
         this.emit("ready");
         return this;
       })
-      .then(null, function onError(aReason) {
+      .catch(function onError(aReason) {
         DevToolsUtils.reportException("DebuggerPanel.prototype.open", aReason);
       });
   },
 
   /**
    * Translate a VK_ keycode, with modifiers, to a key shortcut that can be used with
    * shared/key-shortcut.
    *
--- a/devtools/client/debugger/test/mochitest/browser_dbg_addonactor.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_addonactor.js
@@ -26,17 +26,17 @@ function test() {
     installAddon()
       .then(attachAddonActorForId.bind(null, gClient, ADDON3_ID))
       .then(attachAddonThread)
       .then(testDebugger)
       .then(testSources)
       .then(() => gClient.close())
       .then(uninstallAddon)
       .then(finish)
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function installAddon() {
   return addTemporaryAddon(ADDON3_PATH).then(aAddon => {
     gAddon = aAddon;
--- a/devtools/client/debugger/test/mochitest/browser_dbg_auto-pretty-print-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_auto-pretty-print-02.js
@@ -55,17 +55,17 @@ function test() {
       yield selectFirstSource();
       testFirstSourceLabel();
       testPrettyPrintButtonOn();
 
       // Disable auto pretty printing so it does not affect the following tests.
       yield disableAutoPrettyPrint();
 
       closeDebuggerAndFinish(gPanel)
-        .then(null, aError => {
+        .catch(aError => {
           ok(false, "Got an error: " + DevToolsUtils.safeErrorString(aError));
         });
     });
 
     function selectSecondSource() {
       let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN, 2);
       gSources.selectedIndex = 1;
       return finished;
--- a/devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-01.js
@@ -19,17 +19,17 @@ function test() {
   initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
     gTab = aTab;
     gPanel = aPanel;
     gDebugger = gPanel.panelWin;
 
     testBlackBoxSource()
       .then(testBlackBoxReload)
       .then(() => closeDebuggerAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function testBlackBoxSource() {
   const bbButton = getBlackBoxButton(gPanel);
   ok(!bbButton.checked, "Should not be black boxed by default");
--- a/devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-02.js
@@ -23,17 +23,17 @@ function test() {
     gTab = aTab;
     gPanel = aPanel;
     gDebugger = gPanel.panelWin;
     gFrames = gDebugger.DebuggerView.StackFrames;
 
     testBlackBoxSource()
       .then(testBlackBoxStack)
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function testBlackBoxSource() {
   return toggleBlackBoxing(gPanel).then(source => {
     ok(source.isBlackBoxed, "The source should be black boxed now.");
--- a/devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-03.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-03.js
@@ -25,17 +25,17 @@ function test() {
     gDebugger = gPanel.panelWin;
     gFrames = gDebugger.DebuggerView.StackFrames;
     gSources = gDebugger.DebuggerView.Sources;
 
     waitForSourceAndCaretAndScopes(gPanel, ".html", 21)
       .then(testBlackBoxStack)
       .then(testBlackBoxSource)
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     callInTab(gTab, "runTest");
   });
 }
 
 function testBlackBoxStack() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-04.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-04.js
@@ -24,17 +24,17 @@ function test() {
     gPanel = aPanel;
     gDebugger = gPanel.panelWin;
     gFrames = gDebugger.DebuggerView.StackFrames;
     gSources = gDebugger.DebuggerView.Sources;
 
     blackBoxSources()
       .then(testBlackBoxStack)
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function blackBoxSources() {
   let finished = waitForThreadEvents(gPanel, "blackboxchange", 3);
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-05.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-05.js
@@ -25,17 +25,17 @@ function test() {
     gDeck = gDebugger.document.getElementById("editor-deck");
 
     testSourceEditorShown();
     toggleBlackBoxing(gPanel)
       .then(testBlackBoxMessageShown)
       .then(clickStopBlackBoxingButton)
       .then(testSourceEditorShownAgain)
       .then(() => closeDebuggerAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function testSourceEditorShown() {
   is(gDeck.selectedIndex, "0",
     "The first item in the deck should be selected (the source editor).");
--- a/devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-06.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-06.js
@@ -22,17 +22,17 @@ function test() {
     gTab = aTab;
     gPanel = aPanel;
     gDebugger = gPanel.panelWin;
     gSources = gDebugger.DebuggerView.Sources;
 
     waitForCaretAndScopes(gPanel, 21)
       .then(testBlackBox)
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     callInTab(gTab, "runTest");
   });
 }
 
 function testBlackBox() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-07.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-07.js
@@ -19,17 +19,17 @@ function test() {
   initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
     gTab = aTab;
     gPanel = aPanel;
     gDebugger = gPanel.panelWin;
 
     testBlackBoxSource()
       .then(testBlackBoxReload)
       .then(() => closeDebuggerAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function testBlackBoxSource() {
   const bbButton = getBlackBoxButton(gPanel);
   ok(bbButton.checked, "Should be black boxed by default");
--- a/devtools/client/debugger/test/mochitest/browser_dbg_breadcrumbs-access.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_breadcrumbs-access.js
@@ -24,17 +24,17 @@ function test() {
     gSources = gDebugger.DebuggerView.Sources;
     gFrames = gDebugger.DebuggerView.StackFrames;
 
     waitForSourceAndCaretAndScopes(gPanel, "-02.js", 6)
       .then(checkNavigationWhileNotFocused)
       .then(focusCurrentStackFrame)
       .then(checkNavigationWhileFocused)
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     callInTab(gTab, "firstCall");
   });
 
   function checkNavigationWhileNotFocused() {
     checkState({ frame: 1, source: 1, line: 6 });
--- a/devtools/client/debugger/test/mochitest/browser_dbg_break-on-dom-event-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_break-on-dom-event-01.js
@@ -28,17 +28,17 @@ function test() {
       .then(setupGlobals)
       .then(pauseDebuggee)
       .then(testBreakOnAll)
       .then(testBreakOnDisabled)
       .then(testBreakOnNone)
       .then(testBreakOnClick)
       .then(() => gClient.close())
       .then(finish)
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function setupGlobals(aThreadClient) {
   gThreadClient = aThreadClient;
   gInput = content.document.querySelector("input");
--- a/devtools/client/debugger/test/mochitest/browser_dbg_break-on-dom-event-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_break-on-dom-event-02.js
@@ -26,17 +26,17 @@ function test() {
 
     addTab(TAB_URL)
       .then(() => attachThreadActorForUrl(gClient, TAB_URL))
       .then(aThreadClient => gThreadClient = aThreadClient)
       .then(pauseDebuggee)
       .then(testBreakOnClick)
       .then(() => gClient.close())
       .then(finish)
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function pauseDebuggee() {
   let deferred = promise.defer();
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_chrome-debugging.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_chrome-debugging.js
@@ -30,17 +30,17 @@ function test() {
   gClient = new DebuggerClient(transport);
   gClient.connect().then(([aType, aTraits]) => {
     is(aType, "browser",
       "Root actor should identify itself as a browser.");
 
     promise.all([gAttached.promise, gNewGlobal.promise, gNewChromeSource.promise])
       .then(resumeAndCloseConnection)
       .then(finish)
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     testChromeActor();
   });
 }
 
 function testChromeActor() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_clean-exit-window.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_clean-exit-window.js
@@ -17,17 +17,17 @@ function test() {
     .then(([aTab, aDebuggee, aPanel, aWindow]) => {
       gDebuggee = aDebuggee;
       gPanel = aPanel;
       gDebugger = gPanel.panelWin;
       gWindow = aWindow;
 
       return testCleanExit();
     })
-    .then(null, aError => {
+    .catch(aError => {
       ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
     });
 }
 
 function testCleanExit() {
   let deferred = promise.defer();
 
   ok(!!gWindow, "Second window created.");
--- a/devtools/client/debugger/test/mochitest/browser_dbg_closure-inspection.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_closure-inspection.js
@@ -16,17 +16,17 @@ function test() {
   };
   initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
     gTab = aTab;
     gPanel = aPanel;
     gDebugger = gPanel.panelWin;
 
     testClosure()
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 
   function testClosure() {
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
 
     return waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES).then(() => {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_debugger-statement.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_debugger-statement.js
@@ -28,17 +28,17 @@ function test() {
       .then((aTab) => {
         gTab = aTab;
         return attachTabActorForUrl(gClient, TAB_URL);
       })
       .then(testEarlyDebuggerStatement)
       .then(testDebuggerStatement)
       .then(() => gClient.close())
       .then(finish)
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function testEarlyDebuggerStatement([aGrip, aResponse]) {
   let deferred = promise.defer();
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_editor-contextmenu.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_editor-contextmenu.js
@@ -20,17 +20,17 @@ function test() {
   initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
     gTab = aTab;
     gPanel = aPanel;
     gDebugger = gPanel.panelWin;
     gEditor = gDebugger.DebuggerView.editor;
     gSources = gDebugger.DebuggerView.Sources;
     gContextMenu = gDebugger.document.getElementById("sourceEditorContextMenu");
 
-    waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1).then(performTest).then(null, info);
+    waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1).then(performTest).catch(info);
     callInTab(gTab, "firstCall");
   });
 
   function performTest() {
     is(gDebugger.gThreadClient.state, "paused",
       "Should only be getting stack frames while paused.");
     is(gSources.itemCount, 2,
       "Found the expected number of sources.");
@@ -45,17 +45,17 @@ function test() {
     ok(gContextMenu,
       "The source editor's context menupopup is available.");
     ok(gEditor.getOption("readOnly"),
       "The source editor is read only.");
 
     gEditor.focus();
     gEditor.setSelection({ line: 1, ch: 0 }, { line: 1, ch: 10 });
 
-    once(gContextMenu, "popupshown").then(testContextMenu).then(null, info);
+    once(gContextMenu, "popupshown").then(testContextMenu).catch(info);
     gContextMenu.openPopup(gEditor.container, "overlap", 0, 0, true, false);
   }
 
   function testContextMenu() {
     let document = gDebugger.document;
 
     ok(document.getElementById("editMenuCommands"),
       "#editMenuCommands found.");
--- a/devtools/client/debugger/test/mochitest/browser_dbg_editor-mode.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_editor-mode.js
@@ -25,17 +25,17 @@ function test() {
     gEditor = gDebugger.DebuggerView.editor;
     gSources = gDebugger.DebuggerView.Sources;
 
     waitForSourceAndCaretAndScopes(gPanel, "code_test-editor-mode", 1)
       .then(testInitialSource)
       .then(testSwitch1)
       .then(testSwitch2)
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     callInTab(gTab, "firstCall");
   });
 }
 
 function testInitialSource() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_event-listeners-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_event-listeners-01.js
@@ -28,17 +28,17 @@ function test() {
       .then((aTab) => {
         gTab = aTab;
         return attachThreadActorForUrl(gClient, TAB_URL);
       })
       .then(pauseDebuggee)
       .then(testEventListeners)
       .then(() => gClient.close())
       .then(finish)
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function pauseDebuggee(aThreadClient) {
   let deferred = promise.defer();
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_event-listeners-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_event-listeners-02.js
@@ -29,17 +29,17 @@ function test() {
       .then((aTab) => {
         gTab = aTab;
         return attachThreadActorForUrl(gClient, TAB_URL);
       })
       .then(pauseDebuggee)
       .then(testEventListeners)
       .then(() => gClient.close())
       .then(finish)
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function pauseDebuggee(aThreadClient) {
   let deferred = promise.defer();
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_event-listeners-03.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_event-listeners-03.js
@@ -29,17 +29,17 @@ function test() {
       .then((aTab) => {
         gTab = aTab;
         return attachThreadActorForUrl(gClient, TAB_URL);
       })
       .then(pauseDebuggee)
       .then(testEventListeners)
       .then(() => gClient.close())
       .then(finish)
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function pauseDebuggee(aThreadClient) {
   let deferred = promise.defer();
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_iframes.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_iframes.js
@@ -25,17 +25,17 @@ function test() {
     gIframe = gDebuggee.frames[0];
     gEditor = gDebugger.DebuggerView.editor;
     gSources = gDebugger.DebuggerView.Sources;
     gFrames = gDebugger.DebuggerView.StackFrames;
 
     checkIframeSource();
     checkIframePause()
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 
   function checkIframeSource() {
     is(gDebugger.gThreadClient.paused, false,
       "Should be running after starting the test.");
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_interrupts.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_interrupts.js
@@ -29,17 +29,17 @@ function test() {
     gResumeKey = gDebugger.document.getElementById("resumeKey");
 
     gTarget.on("thread-paused", failOnPause);
     addBreakpoints()
       .then(() => { gTarget.off("thread-paused", failOnPause); })
       .then(testResumeButton)
       .then(testResumeKeyboard)
       .then(() => closeDebuggerAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 
   function failOnPause() {
     ok(false, "A pause was sent, but it shouldn't have been");
   }
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_jump-to-function-definition.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_jump-to-function-definition.js
@@ -21,17 +21,17 @@ function test() {
   initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
     gTab = aTab;
     gPanel = aPanel;
     gDebugger = gPanel.panelWin;
     gSources = gDebugger.DebuggerView.Sources;
 
     jumpToFunctionDefinition()
       .then(() => closeDebuggerAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 
   function jumpToFunctionDefinition() {
     let callLocation = {line: 5, ch: 0};
     let editor = gDebugger.DebuggerView.editor;
     let coords = editor.getCoordsFromPosition(callLocation);
--- a/devtools/client/debugger/test/mochitest/browser_dbg_listaddons.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_listaddons.js
@@ -27,17 +27,17 @@ function test() {
 
     promise.resolve(null)
       .then(testFirstAddon)
       .then(testSecondAddon)
       .then(testRemoveFirstAddon)
       .then(testRemoveSecondAddon)
       .then(() => gClient.close())
       .then(finish)
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function testFirstAddon() {
   let addonListChanged = false;
   gClient.addOneTimeListener("addonListChanged", () => {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_listtabs-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_listtabs-01.js
@@ -26,17 +26,17 @@ function test() {
 
     promise.resolve(null)
       .then(testFirstTab)
       .then(testSecondTab)
       .then(testRemoveTab)
       .then(testAttachRemovedTab)
       .then(() => gClient.close())
       .then(finish)
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function testFirstTab() {
   return addTab(TAB1_URL).then(aTab => {
     gTab1 = aTab;
--- a/devtools/client/debugger/test/mochitest/browser_dbg_multiple-windows.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_multiple-windows.js
@@ -30,17 +30,17 @@ function test() {
       .then(() => addTab(TAB1_URL))
       .then(testFirstTab)
       .then(() => addWindow(TAB2_URL))
       .then(testNewWindow)
       .then(testFocusFirst)
       .then(testRemoveTab)
       .then(() => gClient.close())
       .then(finish)
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function testFirstTab(aTab) {
   let deferred = promise.defer();
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_navigation.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_navigation.js
@@ -24,17 +24,17 @@ function test() {
     is(aType, "browser",
       "Root actor should identify itself as a browser.");
 
     addTab(TAB1_URL)
       .then(() => attachTabActorForUrl(gClient, TAB1_URL))
       .then(testNavigate)
       .then(testDetach)
       .then(finish)
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function testNavigate([aGrip, aResponse]) {
   let outstanding = [promise.defer(), promise.defer()];
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_no-page-sources.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_no-page-sources.js
@@ -21,17 +21,17 @@ function test() {
     gEditor = gDebugger.DebuggerView.editor;
     gSources = gDebugger.DebuggerView.Sources;
     const constants = gDebugger.require("./content/constants");
 
     reloadActiveTab(gPanel);
     waitForNavigation(gPanel)
       .then(testSourcesEmptyText)
       .then(() => closeDebuggerAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function testSourcesEmptyText() {
   is(gSources.itemCount, 0,
       "Found no entries in the sources widget.");
--- a/devtools/client/debugger/test/mochitest/browser_dbg_optimized-out-vars.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_optimized-out-vars.js
@@ -39,12 +39,12 @@ function test() {
 
     let argVar = outerScope.get("arg");
     is(argVar.target.querySelector(".name").getAttribute("value"), "arg",
       "Should have the right property name for |arg|.");
     is(argVar.target.querySelector(".value").getAttribute("value"), 44,
       "Should have the right property value for |arg|.");
 
     yield resumeDebuggerThenCloseAndFinish(panel);
-  }).then(null, aError => {
+  }).catch(aError => {
     ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
   });
 }
--- a/devtools/client/debugger/test/mochitest/browser_dbg_pause-exceptions-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_pause-exceptions-01.js
@@ -34,17 +34,17 @@ function test() {
 
     testPauseOnExceptionsDisabled()
       .then(enablePauseOnExceptions)
       .then(disableIgnoreCaughtExceptions)
       .then(testPauseOnExceptionsEnabled)
       .then(disablePauseOnExceptions)
       .then(enableIgnoreCaughtExceptions)
       .then(() => closeDebuggerAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function testPauseOnExceptionsDisabled() {
   let finished = waitForCaretAndScopes(gPanel, 26).then(() => {
     info("Testing disabled pause-on-exceptions.");
--- a/devtools/client/debugger/test/mochitest/browser_dbg_pause-exceptions-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_pause-exceptions-02.js
@@ -36,17 +36,17 @@ function test() {
       .then(() => reloadActiveTab(gPanel, gDebugger.EVENTS.SOURCE_SHOWN))
       .then(() => {
         generateMouseClickInTab(gTab, "content.document.querySelector('button')");
       })
       .then(testPauseOnExceptionsAfterReload)
       .then(disablePauseOnExceptions)
       .then(enableIgnoreCaughtExceptions)
       .then(() => closeDebuggerAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function testPauseOnExceptionsAfterReload() {
   let finished = waitForCaretAndScopes(gPanel, 19).then(() => {
     info("Testing enabled pause-on-exceptions.");
--- a/devtools/client/debugger/test/mochitest/browser_dbg_paused-keybindings.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_paused-keybindings.js
@@ -39,12 +39,12 @@ function test() {
     executeSoon(function () {
       EventUtils.synthesizeKey("l", { accelKey: true });
       EventUtils.synthesizeKey("1", {});
       EventUtils.synthesizeKey("5", {});
     });
     yield caretMove;
 
     yield resumeDebuggerThenCloseAndFinish(panel);
-  }).then(null, aError => {
+  }).catch(aError => {
     ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
   });
 }
--- a/devtools/client/debugger/test/mochitest/browser_dbg_pretty-print-11.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_pretty-print-11.js
@@ -31,17 +31,17 @@ function test() {
     finished.then(testSourceIsPretty)
       .then(() => {
         const finished = waitForCaretUpdated(gPanel, 7);
         const reloaded = reloadActiveTab(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
         return Promise.all([finished, reloaded]);
       })
       .then(testSourceIsPretty)
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + DevToolsUtils.safeErrorString(aError));
       });
   });
 }
 
 function testSourceIsUgly() {
   ok(!gEditor.getText().includes("\n  "),
      "The source shouldn't be pretty printed yet.");
--- a/devtools/client/debugger/test/mochitest/browser_dbg_promises-allocation-stack.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_promises-allocation-stack.js
@@ -30,17 +30,17 @@ function test() {
     let { tabs } = yield listTabs(client);
     let targetTab = findTab(tabs, TAB_URL);
     yield attachTab(client, targetTab);
 
     yield testGetAllocationStack(client, targetTab, tab);
 
     yield close(client);
     yield closeDebuggerAndFinish(panel);
-  }).then(null, error => {
+  }).catch(error => {
     ok(false, "Got an error: " + error.message + "\n" + error.stack);
   });
 }
 
 function* testGetAllocationStack(client, form, tab) {
   let front = PromisesFront(client, form);
 
   yield front.attach();
--- a/devtools/client/debugger/test/mochitest/browser_dbg_promises-chrome-allocation-stack.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_promises-chrome-allocation-stack.js
@@ -33,23 +33,23 @@ function test() {
     let [, tabClient] = yield attachTab(client, chrome.form);
     yield tabClient.attachThread();
 
     yield testGetAllocationStack(client, chrome.form, () => {
       let p = new Promise(() => {});
       p.name = "p";
       let q = p.then();
       q.name = "q";
-      let r = p.then(null, () => {});
+      let r = p.catch(() => {});
       r.name = "r";
     });
 
     yield close(client);
     finish();
-  }).then(null, error => {
+  }).catch(error => {
     ok(false, "Got an error: " + error.message + "\n" + error.stack);
   });
 }
 
 function* testGetAllocationStack(client, form, makePromises) {
   let front = PromisesFront(client, form);
 
   yield front.attach();
--- a/devtools/client/debugger/test/mochitest/browser_dbg_promises-fulfillment-stack.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_promises-fulfillment-stack.js
@@ -48,17 +48,17 @@ function test() {
     let { tabs } = yield listTabs(client);
     let targetTab = findTab(tabs, TAB_URL);
     yield attachTab(client, targetTab);
 
     yield testGetFulfillmentStack(client, targetTab, tab);
 
     yield close(client);
     yield closeDebuggerAndFinish(panel);
-  }).then(null, error => {
+  }).catch(error => {
     ok(false, "Got an error: " + error.message + "\n" + error.stack);
   });
 }
 
 function* testGetFulfillmentStack(client, form, tab) {
   let front = PromisesFront(client, form);
 
   yield front.attach();
--- a/devtools/client/debugger/test/mochitest/browser_dbg_promises-rejection-stack.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_promises-rejection-stack.js
@@ -55,17 +55,17 @@ function test() {
     let { tabs } = yield listTabs(client);
     let targetTab = findTab(tabs, TAB_URL);
     yield attachTab(client, targetTab);
 
     yield testGetRejectionStack(client, targetTab, tab);
 
     yield close(client);
     yield closeDebuggerAndFinish(panel);
-  }).then(null, error => {
+  }).catch(error => {
     ok(false, "Got an error: " + error.message + "\n" + error.stack);
   });
 }
 
 function* testGetRejectionStack(client, form, tab) {
   let front = PromisesFront(client, form);
 
   yield front.attach();
--- a/devtools/client/debugger/test/mochitest/browser_dbg_reload-preferred-script-03.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_reload-preferred-script-03.js
@@ -27,17 +27,17 @@ function test() {
     gSources = gDebugger.DebuggerView.Sources;
 
     testSource(undefined, FIRST_URL);
     switchToSource(SECOND_URL)
       .then(() => testSource(SECOND_URL))
       .then(() => switchToSource(FIRST_URL))
       .then(() => testSource(FIRST_URL))
       .then(() => closeDebuggerAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function testSource(aPreferredUrl, aSelectedUrl = aPreferredUrl) {
   info("Currently preferred source: " + gSources.preferredValue);
   info("Currently selected source: " + gSources.selectedValue);
--- a/devtools/client/debugger/test/mochitest/browser_dbg_search-basic-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_search-basic-02.js
@@ -30,17 +30,17 @@ function test() {
       .then(() => verifySourceAndCaret("-01.js", 1, 1, [1, 1]))
       .then(combineWithLineSearch)
       .then(() => verifySourceAndCaret("-01.js", 2, 1, [53, 53]))
       .then(combineWithTokenSearch)
       .then(() => verifySourceAndCaret("-01.js", 2, 48, [96, 100]))
       .then(combineWithTokenColonSearch)
       .then(() => verifySourceAndCaret("-01.js", 2, 11, [56, 63]))
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     callInTab(gTab, "firstCall");
   });
 }
 
 function performSimpleSearch() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_search-basic-03.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_search-basic-03.js
@@ -32,17 +32,17 @@ function test() {
       .then(performFunctionSearch)
       .then(escapeAndHide)
       .then(escapeAndClear)
       .then(() => verifySourceAndCaret("-01.js", 4, 10))
       .then(performGlobalSearch)
       .then(escapeAndClear)
       .then(() => verifySourceAndCaret("-01.js", 4, 10))
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     callInTab(gTab, "firstCall");
   });
 }
 
 function performFileSearch() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_search-global-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_search-global-01.js
@@ -27,17 +27,17 @@ function test() {
     gSearchView = gDebugger.DebuggerView.GlobalSearch;
     gSearchBox = gDebugger.DebuggerView.Filtering._searchbox;
 
     waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1)
       .then(firstSearch)
       .then(secondSearch)
       .then(clearSearch)
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     callInTab(gTab, "firstCall");
   });
 }
 
 function firstSearch() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_search-global-03.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_search-global-03.js
@@ -26,17 +26,17 @@ function test() {
     gSources = gDebugger.DebuggerView.Sources;
     gSearchView = gDebugger.DebuggerView.GlobalSearch;
     gSearchBox = gDebugger.DebuggerView.Filtering._searchbox;
 
     waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1)
       .then(firstSearch)
       .then(performTest)
       .then(() => closeDebuggerAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     callInTab(gTab, "firstCall");
   });
 }
 
 function firstSearch() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_search-global-04.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_search-global-04.js
@@ -26,17 +26,17 @@ function test() {
     gSources = gDebugger.DebuggerView.Sources;
     gSearchView = gDebugger.DebuggerView.GlobalSearch;
     gSearchBox = gDebugger.DebuggerView.Filtering._searchbox;
 
     waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1)
       .then(firstSearch)
       .then(secondSearch)
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     callInTab(gTab, "firstCall");
   });
 }
 
 function firstSearch() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_search-global-05.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_search-global-05.js
@@ -29,17 +29,17 @@ function test() {
     gSearchBox = gDebugger.DebuggerView.Filtering._searchbox;
 
     waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1)
       .then(doSearch)
       .then(testExpandCollapse)
       .then(testClickLineToJump)
       .then(testClickMatchToJump)
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     callInTab(gTab, "firstCall");
   });
 }
 
 function doSearch() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_search-global-06.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_search-global-06.js
@@ -28,17 +28,17 @@ function test() {
     gSearchBox = gDebugger.DebuggerView.Filtering._searchbox;
 
     waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1)
       .then(doSearch)
       .then(testFocusLost)
       .then(doSearch)
       .then(testEscape)
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     callInTab(gTab, "firstCall");
   });
 }
 
 function doSearch() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_search-popup-jank.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_search-popup-jank.js
@@ -70,17 +70,17 @@ function test() {
       .then(superGenericFunctionSearch)
       .then(() => ensureSourceIs(aPanel, "code_test-editor-mode"))
       .then(() => ensureCaretAt(aPanel, 6))
       .then(() => pressKey("RETURN"))
       .then(() => ensureSourceIs(aPanel, "code_test-editor-mode"))
       .then(() => ensureCaretAt(aPanel, 4, 10))
 
       .then(() => closeDebuggerAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function waitForMatchFoundAndResultsShown(aName) {
   return promise.all([
     once(gDebugger, "popupshown"),
--- a/devtools/client/debugger/test/mochitest/browser_dbg_search-sources-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_search-sources-01.js
@@ -33,17 +33,17 @@ function test() {
       yield secondSearch();
       yield thirdSearch();
       yield fourthSearch();
       yield fifthSearch();
       yield sixthSearch();
       yield seventhSearch();
 
       return closeDebuggerAndFinish(gPanel)
-        .then(null, aError => {
+        .catch(aError => {
           ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
         });
     });
 
     function bogusSearch() {
       let finished = promise.all([
         ensureSourceIs(gPanel, "-01.js"),
         ensureCaretAt(gPanel, 1),
--- a/devtools/client/debugger/test/mochitest/browser_dbg_search-sources-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_search-sources-02.js
@@ -37,17 +37,17 @@ function test() {
       .then(goDown)
       .then(goDownAndWrap)
       .then(goUpAndWrap)
       .then(goUp)
       .then(returnAndSwitch)
       .then(firstSearch)
       .then(clickAndSwitch)
       .then(() => closeDebuggerAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function firstSearch() {
   let finished = promise.all([
     ensureSourceIs(gPanel, "-01.js"),
--- a/devtools/client/debugger/test/mochitest/browser_dbg_search-sources-03.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_search-sources-03.js
@@ -28,17 +28,17 @@ function test() {
       .then(verifySourcesPane)
       .then(kindaInterpretableSearch)
       .then(verifySourcesPane)
       .then(incrediblySpecificSearch)
       .then(verifySourcesPane)
       .then(returnAndHide)
       .then(verifySourcesPane)
       .then(() => closeDebuggerAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function waitForMatchFoundAndResultsShown() {
   return promise.all([
     once(gDebugger, "popupshown"),
--- a/devtools/client/debugger/test/mochitest/browser_dbg_search-symbols.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_search-symbols.js
@@ -35,17 +35,17 @@ function test() {
       .then(() => showSource("code_function-search-03.js"))
       .then(thirdJsSearch)
       .then(saveSearch)
       .then(filterSearch)
       .then(bogusSearch)
       .then(incrementalSearch)
       .then(emptySearch)
       .then(() => closeDebuggerAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function htmlSearch() {
   let deferred = promise.defer();
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_searchbox-help-popup-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_searchbox-help-popup-01.js
@@ -24,17 +24,17 @@ function test() {
     gDebugger = gPanel.panelWin;
     gSearchBox = gDebugger.DebuggerView.Filtering._searchbox;
     gSearchBoxPanel = gDebugger.DebuggerView.Filtering._searchboxHelpPanel;
 
     waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1)
       .then(showPopup)
       .then(hidePopup)
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     callInTab(gTab, "firstCall");
   });
 }
 
 function showPopup() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_searchbox-help-popup-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_searchbox-help-popup-02.js
@@ -30,17 +30,17 @@ function test() {
       ok(false, "Damn it, this shouldn't have happened.");
     });
 
     waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1)
       .then(tryShowPopup)
       .then(focusEditor)
       .then(testFocusLost)
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     callInTab(gTab, "firstCall");
   });
 }
 
 function tryShowPopup() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_source-maps-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_source-maps-01.js
@@ -29,17 +29,17 @@ function test() {
     checkSourceMapsEnabled();
 
     checkInitialSource();
     testSetBreakpoint()
       .then(testSetBreakpointBlankLine)
       .then(testHitBreakpoint)
       .then(testStepping)
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function checkSourceMapsEnabled() {
   is(Services.prefs.getBoolPref("devtools.debugger.source-maps-enabled"), true,
     "The source maps functionality should be enabled by default.");
--- a/devtools/client/debugger/test/mochitest/browser_dbg_source-maps-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_source-maps-02.js
@@ -28,17 +28,17 @@ function test() {
     gPrefs = gDebugger.Prefs;
     gOptions = gDebugger.DebuggerView.Options;
 
     testToggleGeneratedSource()
       .then(testSetBreakpoint)
       .then(testToggleOnPause)
       .then(testResume)
       .then(() => closeDebuggerAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function testToggleGeneratedSource() {
   let finished = waitForSourceShown(gPanel, ".js").then(() => {
     is(gPrefs.sourceMapsEnabled, false,
--- a/devtools/client/debugger/test/mochitest/browser_dbg_source-maps-03.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_source-maps-03.js
@@ -24,17 +24,17 @@ function test() {
     gDebugger = gPanel.panelWin;
     gEditor = gDebugger.DebuggerView.editor;
     gSources = gDebugger.DebuggerView.Sources;
     gFrames = gDebugger.DebuggerView.StackFrames;
 
     checkInitialSource()
     testSetBreakpoint()
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function checkInitialSource() {
   isnot(gSources.selectedItem.attachment.source.url.indexOf(".js"), -1,
     "The debugger should not show the minified js file.");
--- a/devtools/client/debugger/test/mochitest/browser_dbg_source-maps-04.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_source-maps-04.js
@@ -38,17 +38,17 @@ function test() {
     enablePauseOnExceptions()
       .then(disableIgnoreCaughtExceptions)
       .then(testSetBreakpoint)
       .then(reloadPage)
       .then(testHitBreakpoint)
       .then(enableIgnoreCaughtExceptions)
       .then(disablePauseOnExceptions)
       .then(() => closeDebuggerAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function checkInitialSource() {
   isnot(gSources.selectedItem.attachment.source.url.indexOf("code_math_bogus_map.js"), -1,
     "The debugger should show the minified js file.");
--- a/devtools/client/debugger/test/mochitest/browser_dbg_sources-contextmenu-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_sources-contextmenu-01.js
@@ -21,17 +21,17 @@ function test() {
     gTab = aTab;
     gPanel = aPanel;
     gDebugger = gPanel.panelWin;
     gSources = gDebugger.DebuggerView.Sources;
 
     openContextMenu()
       .then(testCopyMenuItem)
       .then(() => closeDebuggerAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 
   function clickCopyURL() {
     return new Promise((resolve, reject) => {
       let copyURLMenuItem = gDebugger.document.getElementById("debugger-sources-context-copyurl");
       if (!copyURLMenuItem) {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_sources-contextmenu-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_sources-contextmenu-02.js
@@ -23,17 +23,17 @@ function test() {
     gPanel = aPanel;
     gDebugger = gPanel.panelWin;
     gSources = gDebugger.DebuggerView.Sources;
 
     openContextMenu()
       .then(testNewTabMenuItem)
       .then(testNewTabURI)
       .then(() => closeDebuggerAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 
   function testNewTabURI(tabUri) {
     is(tabUri, SCRIPT_URI, "The tab contains the right script.");
     gBrowser.removeCurrentTab();
   }
--- a/devtools/client/debugger/test/mochitest/browser_dbg_sources-keybindings.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_sources-keybindings.js
@@ -20,17 +20,17 @@ function test() {
   initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
     gTab = aTab;
     gPanel = aPanel;
     gDebugger = gPanel.panelWin;
     gSources = gDebugger.DebuggerView.Sources;
 
     testCopyURLShortcut()
       .then(() => closeDebuggerAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 
   function testCopyURLShortcut() {
     return waitForClipboardPromise(sendCopyShortcut, SCRIPT_URI);
   }
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_stack-contextmenu-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_stack-contextmenu-02.js
@@ -21,17 +21,17 @@ function test() {
     gPanel = aPanel;
     gDebugger = gPanel.panelWin;
     gFrames = gDebugger.DebuggerView.StackFrames;
 
     waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_REFILLED)
      .then(openContextMenu)
      .then(testCopyStackMenuItem)
      .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-     .then(null, aError => {
+     .catch(aError => {
        ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
      });
     callInTab(gTab, "simpleCall");
   });
 
   function clickCopyStack() {
     return new Promise((resolve, reject) => {
       let copyStackMenuItem = gDebugger.document.getElementById("copyStackMenuItem");
--- a/devtools/client/debugger/test/mochitest/browser_dbg_tabactor-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_tabactor-01.js
@@ -27,17 +27,17 @@ function test() {
       "Root actor should identify itself as a browser.");
 
     addTab(TAB_URL)
       .then(() => attachTabActorForUrl(gClient, TAB_URL))
       .then(testTabActor)
       .then(closeTab)
       .then(() => gClient.close())
       .then(finish)
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function testTabActor([aGrip, aResponse]) {
   let deferred = promise.defer();
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_tabactor-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_tabactor-02.js
@@ -27,17 +27,17 @@ function test() {
       "Root actor should identify itself as a browser.");
 
     addTab(TAB_URL)
       .then(() => attachTabActorForUrl(gClient, TAB_URL))
       .then(testTabActor)
       .then(closeTab)
       .then(() => gClient.close())
       .then(finish)
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function testTabActor([aGrip, aResponse]) {
   let deferred = promise.defer();
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-accessibility.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-accessibility.js
@@ -12,17 +12,17 @@ var gVariablesView;
 
 function test() {
   initDebugger().then(([aTab,, aPanel]) => {
     gTab = aTab;
     gPanel = aPanel;
     gDebugger = gPanel.panelWin;
     gVariablesView = gDebugger.DebuggerView.Variables;
 
-    performTest().then(null, aError => {
+    performTest().catch(aError => {
       ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
     });
   });
 }
 
 function performTest() {
   let arr = [
     42,
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-getset-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-getset-01.js
@@ -111,17 +111,17 @@ function test() {
       }))
       .then(() => deleteWatchExpression("myVar.prop + 42"))
       .then(() => testEdit("self", "0910", {
         "myVar.prop": 910
       }))
       .then(() => deleteLastWatchExpression("myVar.prop"))
       .then(() => testWatchExpressionsRemoved())
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function addWatchExpressions() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-getset-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-getset-02.js
@@ -32,17 +32,17 @@ function test() {
 
     gVars.switch = function () {};
     gVars.delete = function () {};
 
     waitForCaretAndScopes(gPanel, 24)
       .then(() => addWatchExpression())
       .then(() => testEdit("\"xlerb\"", "xlerb"))
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function addWatchExpression() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-value-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-value-01.js
@@ -34,17 +34,17 @@ function test() {
       .then(() => testModification("Infinity", "Infinity"))
       .then(() => testModification("NaN", "NaN"))
       .then(() => testModification("new Function", "anonymous()"))
       .then(() => testModification("+0", "0"))
       .then(() => testModification("-0", "-0"))
       .then(() => testModification("Object.keys({})", "Array[0]"))
       .then(() => testModification("document.title", '"Debugger test page"'))
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function initialChecks() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-value-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-value-02.js
@@ -29,17 +29,17 @@ function test() {
       let expanded = once(gVars, "fetched");
       obj.expand();
       return expanded;
     }).then(() => initialCheck("\u2028", "\\u2028", "8"))
       .then(() => initialCheck("\u2029", "\\u2029", "9"))
       .then(() => testModification("\u2028", "\\u2028", "123", "123"))
       .then(() => testModification("\u2029", "\\u2029", "456", "456"))
       .then(() => resumeDebuggerThenCloseAndFinish(panel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function getObjectScope() {
   return gVars.getScopeAtIndex(0).get("obj");
 }
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-watch.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-watch.js
@@ -41,17 +41,17 @@ function test() {
       .then(() => testIntegrity4())
       .then(() => testModification("document.title", "\ \t\r\n", "\"43\"", "44"))
       .then(() => testIntegrity5())
       .then(() => testExprDeletion("this", "44"))
       .then(() => testIntegrity6())
       .then(() => testExprFinalDeletion("ermahgerd", "44"))
       .then(() => testIntegrity7())
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     addExpressions();
     callInTab(gTab, "ermahgerd");
   });
 }
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-01.js
@@ -32,17 +32,17 @@ function test() {
     // The first 'with' scope should be expanded by default, but the
     // variables haven't been fetched yet. This is how 'with' scopes work.
     promise.all([
       waitForCaretAndScopes(gPanel, 22),
       waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES)
     ]).then(prepareVariablesAndProperties)
       .then(testVariablesAndPropertiesFiltering)
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function testVariablesAndPropertiesFiltering() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-02.js
@@ -32,17 +32,17 @@ function test() {
     // The first 'with' scope should be expanded by default, but the
     // variables haven't been fetched yet. This is how 'with' scopes work.
     promise.all([
       waitForCaretAndScopes(gPanel, 22),
       waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES)
     ]).then(prepareVariablesAndProperties)
       .then(testVariablesAndPropertiesFiltering)
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function testVariablesAndPropertiesFiltering() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-03.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-03.js
@@ -31,17 +31,17 @@ function test() {
     // The first 'with' scope should be expanded by default, but the
     // variables haven't been fetched yet. This is how 'with' scopes work.
     promise.all([
       waitForCaretAndScopes(gPanel, 22),
       waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES)
     ]).then(prepareVariablesAndProperties)
       .then(testVariablesAndPropertiesFiltering)
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function testVariablesAndPropertiesFiltering() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-04.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-04.js
@@ -32,17 +32,17 @@ function test() {
     // The first 'with' scope should be expanded by default, but the
     // variables haven't been fetched yet. This is how 'with' scopes work.
     promise.all([
       waitForCaretAndScopes(gPanel, 22),
       waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES)
     ]).then(prepareVariablesAndProperties)
       .then(testVariablesAndPropertiesFiltering)
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function testVariablesAndPropertiesFiltering() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-05.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-05.js
@@ -31,17 +31,17 @@ function test() {
     // The first 'with' scope should be expanded by default, but the
     // variables haven't been fetched yet. This is how 'with' scopes work.
     promise.all([
       waitForCaretAndScopes(gPanel, 22),
       waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES)
     ]).then(prepareVariablesAndProperties)
       .then(testVariablesAndPropertiesFiltering)
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function testVariablesAndPropertiesFiltering() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-frame-parameters-01.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-frame-parameters-01.js
@@ -26,17 +26,17 @@ function test() {
     gPanel = aPanel;
     gDebugger = gPanel.panelWin;
     gVariables = gDebugger.DebuggerView.Variables;
 
     waitForCaretAndScopes(gPanel, 24)
       .then(initialChecks)
       .then(testExpandVariables)
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function initialChecks() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-frame-parameters-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-frame-parameters-02.js
@@ -31,17 +31,17 @@ function test() {
       .then(testScopeVariables)
       .then(testArgumentsProperties)
       .then(testSimpleObject)
       .then(testComplexObject)
       .then(testArgumentObject)
       .then(testInnerArgumentObject)
       .then(testGetterSetterObject)
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function testScopeVariables() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-frame-parameters-03.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-frame-parameters-03.js
@@ -28,17 +28,17 @@ function test() {
     gVariables = gDebugger.DebuggerView.Variables;
 
     waitForCaretAndScopes(gPanel, 24)
       .then(expandGlobalScope)
       .then(testGlobalScope)
       .then(expandWindowVariable)
       .then(testWindowVariable)
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function expandGlobalScope() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-frame-with.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-frame-with.js
@@ -29,17 +29,17 @@ function test() {
       waitForCaretAndScopes(gPanel, 22),
       waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES)
     ]).then(testFirstWithScope)
       .then(expandSecondWithScope)
       .then(testSecondWithScope)
       .then(expandFunctionScope)
       .then(testFunctionScope)
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function testFirstWithScope() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-large-array-buffer.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-large-array-buffer.js
@@ -28,17 +28,17 @@ function test() {
     gTab = aTab;
     gPanel = aPanel;
     gDebugger = gPanel.panelWin;
     gVariables = gDebugger.DebuggerView.Variables;
 
     waitForCaretAndScopes(gPanel, 28, 1)
       .then(() => performTests())
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, error => {
+      .catch(error => {
         ok(false, "Got an error: " + error.message + "\n" + error.stack);
       });
 
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 const VARS_TO_TEST = [
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-webidl.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-webidl.js
@@ -26,17 +26,17 @@ function test() {
     gPanel = aPanel;
     gDebugger = gPanel.panelWin;
     gVariables = gDebugger.DebuggerView.Variables;
 
     waitForCaretAndScopes(gPanel, 24)
       .then(expandGlobalScope)
       .then(performTest)
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
 
     generateMouseClickInTab(gTab, "content.document.querySelector('button')");
   });
 }
 
 function expandGlobalScope() {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_watch-expressions-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_watch-expressions-02.js
@@ -28,17 +28,17 @@ function test() {
     gVariables = gDebugger.DebuggerView.Variables;
 
     gDebugger.DebuggerView.toggleInstrumentsPane({ visible: true, animated: false });
 
     addExpressions();
     performTest()
       .then(finishTest)
       .then(() => closeDebuggerAndFinish(gPanel))
-      .then(null, aError => {
+      .catch(aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 
   function addExpressions() {
     // https://bugzilla.mozilla.org/show_bug.cgi?id=1205353
     // BZ#1205353 - wrong result for string replace with backslash-dollar.
     gWatch.addExpression("'$$$'.replace(/\\$/, 'foo')");
--- a/devtools/client/debugger/test/mochitest/doc_promise-get-allocation-stack.html
+++ b/devtools/client/debugger/test/mochitest/doc_promise-get-allocation-stack.html
@@ -10,15 +10,15 @@
 
   <body>
     <script type="text/javascript">
       function makePromises() {
         var p = new Promise(() => {});
         p.name = "p";
         var q = p.then();
         q.name = "q";
-        var r = p.then(null, () => {});
+        var r = p.catch(() => {});
         r.name = "r";
       }
     </script>
   </body>
 
 </html>
--- a/devtools/client/debugger/test/mochitest/doc_promise.html
+++ b/devtools/client/debugger/test/mochitest/doc_promise.html
@@ -18,13 +18,13 @@
       var p = window.pending;
       var f = window.fulfilled;
       var r = window.rejected;
       debugger;
     };
 
     // Attach an error handler so that the logs don't have a warning about an
     // unhandled, rejected promise.
-    window.rejected.then(null, function () {});
+    window.rejected.catch(function () {});
     </script>
   </body>
 
 </html>
--- a/devtools/client/debugger/views/variable-bubble-view.js
+++ b/devtools/client/debugger/views/variable-bubble-view.js
@@ -151,17 +151,17 @@ VariableBubbleView.prototype = {
             objectActor: frameFinished.return
           });
         } else {
           let msg = "Evaluation has thrown for: " + identifierInfo.evalString;
           console.warn(msg);
           dumpn(msg);
         }
       })
-      .then(null, err => {
+      .catch(err => {
         let msg = "Couldn't evaluate: " + err.message;
         console.error(msg);
         dumpn(msg);
       });
   },
 
   /**
    * Shows an inspection popup for a specified object actor grip.
--- a/devtools/client/devtools-startup.js
+++ b/devtools/client/devtools-startup.js
@@ -71,17 +71,17 @@ DevToolsStartup.prototype = {
   handleConsoleFlag: function (cmdLine) {
     let window = Services.wm.getMostRecentWindow("devtools:webconsole");
     if (!window) {
       this.initDevTools();
 
       let { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
       let hudservice = require("devtools/client/webconsole/hudservice");
       let { console } = Cu.import("resource://gre/modules/Console.jsm", {});
-      hudservice.toggleBrowserConsole().then(null, console.error);
+      hudservice.toggleBrowserConsole().catch(console.error);
     } else {
       // the Browser Console was already open
       window.focus();
     }
 
     if (cmdLine.state == Ci.nsICommandLine.STATE_REMOTE_AUTO) {
       cmdLine.preventDefault = true;
     }
--- a/devtools/client/framework/test/browser_toolbox_custom_host.js
+++ b/devtools/client/framework/test/browser_toolbox_custom_host.js
@@ -15,17 +15,17 @@ function test() {
   iframe = document.createElement("iframe");
   document.documentElement.appendChild(iframe);
 
   addTab(TEST_URL).then(function (tab) {
     target = TargetFactory.forTab(tab);
     let options = {customIframe: iframe};
     gDevTools.showToolbox(target, null, Toolbox.HostType.CUSTOM, options)
              .then(testCustomHost, console.error)
-             .then(null, console.error);
+             .catch(console.error);
   });
 
   function onMessage(event) {
     if (typeof(event.data) !== "string") {
       return;
     }
     info("onMessage: " + event.data);
     let json = JSON.parse(event.data);
--- a/devtools/client/framework/test/browser_toolbox_raise.js
+++ b/devtools/client/framework/test/browser_toolbox_raise.js
@@ -10,32 +10,32 @@ var {Toolbox} = require("devtools/client
 var toolbox, tab1, tab2;
 
 function test() {
   addTab(TEST_URL).then(tab => {
     tab2 = BrowserTestUtils.addTab(gBrowser);
     let target = TargetFactory.forTab(tab);
     gDevTools.showToolbox(target)
              .then(testBottomHost, console.error)
-             .then(null, console.error);
+             .catch(console.error);
   });
 }
 
 function testBottomHost(aToolbox) {
   toolbox = aToolbox;
 
   // switch to another tab and test toolbox.raise()
   gBrowser.selectedTab = tab2;
   executeSoon(function () {
     is(gBrowser.selectedTab, tab2, "Correct tab is selected before calling raise");
     toolbox.raise();
     executeSoon(function () {
       is(gBrowser.selectedTab, tab1, "Correct tab was selected after calling raise");
 
-      toolbox.switchHost(Toolbox.HostType.WINDOW).then(testWindowHost).then(null, console.error);
+      toolbox.switchHost(Toolbox.HostType.WINDOW).then(testWindowHost).catch(console.error);
     });
   });
 }
 
 function testWindowHost() {
   // Make sure toolbox is not focused.
   window.addEventListener("focus", onFocus, true);
 
--- a/devtools/client/framework/test/browser_toolbox_sidebar.js
+++ b/devtools/client/framework/test/browser_toolbox_sidebar.js
@@ -84,17 +84,17 @@ function test() {
         allTabsReady(panel);
       });
 
       panel.sidebar.addTab("tab1", tab1URL, {selected: true});
       panel.sidebar.addTab("tab2", tab2URL);
       panel.sidebar.addTab("tab3", tab3URL);
 
       panel.sidebar.show();
-    }).then(null, console.error);
+    }).catch(console.error);
   });
 
   function allTabsReady(panel) {
     if (!tab1Selected || !readyTabs.tab1 || !readyTabs.tab2 || !readyTabs.tab3) {
       return;
     }
 
     ok(registeredTabs.tab1, "tab1 registered");
--- a/devtools/client/framework/test/browser_toolbox_sidebar_events.js
+++ b/devtools/client/framework/test/browser_toolbox_sidebar_events.js
@@ -64,17 +64,17 @@ function test() {
 
       panel.sidebar.once("hide", function (event, id) {
         collectedEvents.push(event);
       });
 
       panel.sidebar.once("tab1-selected", () => finishUp(panel));
       panel.sidebar.addTab("tab1", tab1URL, {selected: true});
       panel.sidebar.show();
-    }).then(null, console.error);
+    }).catch(console.error);
   });
 
   function finishUp(panel) {
     panel.sidebar.hide();
     panel.sidebar.destroy();
 
     let events = collectedEvents.join(":");
     is(events, "sidebar-created:show:hide:sidebar-destroyed",
--- a/devtools/client/framework/toolbox.js
+++ b/devtools/client/framework/toolbox.js
@@ -505,17 +505,17 @@ Toolbox.prototype = {
       // so we don't have to explicitly wait for this in tests; ideally, all tests
       // will handle this on their own, but each have their own tear down function.
       if (flags.testing) {
         yield performanceFrontConnection;
       }
 
       this.emit("ready");
       this._isOpenDeferred.resolve();
-    }.bind(this)).then(null, console.error.bind(console));
+    }.bind(this)).catch(console.error.bind(console));
   },
 
   /**
    * loading React modules when needed (to avoid performance penalties
    * during Firefox start up time).
    */
   get React() {
     return this.browserRequire("devtools/client/shared/vendor/react");
@@ -2474,17 +2474,17 @@ Toolbox.prototype = {
 
           // Force GC to prevent long GC pauses when running tests and to free up
           // memory in general when the toolbox is closed.
           if (flags.testing) {
             win.QueryInterface(Ci.nsIInterfaceRequestor)
               .getInterface(Ci.nsIDOMWindowUtils)
               .garbageCollect();
           }
-        }).then(null, console.error));
+        }).catch(console.error));
 
     let leakCheckObserver = ({wrappedJSObject: barrier}) => {
       // Make the leak detector wait until this toolbox is properly destroyed.
       barrier.client.addBlocker("DevTools: Wait until toolbox is destroyed",
                                 this._destroyer);
     };
 
     let topic = "shutdown-leaks-before-check";
--- a/devtools/client/inspector/computed/computed.js
+++ b/devtools/client/inspector/computed/computed.js
@@ -507,17 +507,17 @@ CssComputedView.prototype = {
 
             this.inspector.emit("computed-view-refreshed");
             deferred.resolve(undefined);
           }
         }
       );
       this._refreshProcess.schedule();
       return deferred.promise;
-    }).then(null, (err) => console.error(err));
+    }).catch((err) => console.error(err));
   },
 
   /**
    * Handle the shortcut events in the computed view.
    */
   _onShortcut: function (name, event) {
     if (!event.target.closest("#sidebar-panel-computedview")) {
       return;
@@ -671,17 +671,17 @@ CssComputedView.prototype = {
         CssComputedView.propertyNames.push(prop);
       }
     }
 
     CssComputedView.propertyNames.sort();
     CssComputedView.propertyNames.push.apply(CssComputedView.propertyNames,
       mozProps.sort());
 
-    this._createPropertyViews().then(null, e => {
+    this._createPropertyViews().catch(e => {
       if (!this._isDestroyed) {
         console.warn("The creation of property views was cancelled because " +
           "the computed-view was destroyed before it was done creating views");
       } else {
         console.error(e);
       }
     });
   },
@@ -1103,17 +1103,17 @@ PropertyView.prototype = {
           }
 
           this._matchedSelectorResponse = matched;
 
           return this._buildMatchedSelectors().then(() => {
             this.matchedExpander.setAttribute("open", "");
             this.tree.inspector.emit("computed-view-property-expanded");
           });
-        }).then(null, console.error);
+        }).catch(console.error);
     }
 
     this.matchedSelectorsContainer.innerHTML = "";
     this.matchedExpander.removeAttribute("open");
     this.tree.inspector.emit("computed-view-property-collapsed");
     return promise.resolve(undefined);
   },
 
--- a/devtools/client/inspector/fonts/fonts.js
+++ b/devtools/client/inspector/fonts/fonts.js
@@ -165,20 +165,20 @@ FontInspector.prototype = {
       includePreviews: true,
       previewText: this.getPreviewText(),
       previewFillStyle: getColor("body-color")
     };
 
     let fonts = [];
     if (showAllFonts) {
       fonts = yield this.pageStyle.getAllUsedFontFaces(options)
-                      .then(null, console.error);
+                      .catch(console.error);
     } else {
       fonts = yield this.pageStyle.getUsedFontFaces(node, options)
-                      .then(null, console.error);
+                      .catch(console.error);
     }
 
     if (!fonts || !fonts.length) {
       // No fonts to display. Clear the previously shown fonts.
       this.clear();
       return;
     }
 
--- a/devtools/client/inspector/inspector.js
+++ b/devtools/client/inspector/inspector.js
@@ -2147,15 +2147,15 @@ if (window.location.protocol === "chrome
     let target = yield targetFromURL(url);
     let fakeToolbox = yield buildFakeToolbox(
       target,
       (toolbox) => attachThread(toolbox),
       { React, ReactDOM, browserRequire }
     );
     let inspectorUI = new Inspector(fakeToolbox);
     inspectorUI.init();
-  }).then(null, e => {
+  }).catch(e => {
     window.alert("Unable to start the inspector:" + e.message + "\n" + e.stack);
   });
 }
 
 exports.Inspector = Inspector;
 exports.buildFakeToolbox = buildFakeToolbox;
--- a/devtools/client/inspector/markup/markup.js
+++ b/devtools/client/inspector/markup/markup.js
@@ -899,17 +899,17 @@ MarkupView.prototype = {
             this.navigate(this.getContainer(focusNode));
           }
         });
       }, () => {
         let isValidSibling = nextSibling && !nextSibling.isPseudoElement;
         nextSibling = isValidSibling ? nextSibling : null;
         this.walker.insertBefore(node, parent, nextSibling);
       });
-    }).then(null, console.error);
+    }).catch(console.error);
   },
 
   /**
    * If an editable item is focused, select its container.
    */
   _onFocus: function (event) {
     let parent = event.target;
     while (!parent.container) {
@@ -1167,17 +1167,17 @@ MarkupView.prototype = {
     return this._expandContainer(container).then(() => {
       let child = container.children.firstChild;
       let promises = [];
       while (child) {
         promises.push(this._expandAll(child.container));
         child = child.nextSibling;
       }
       return promise.all(promises);
-    }).then(null, console.error);
+    }).catch(console.error);
   },
 
   /**
    * Expand the entire tree beneath a node.
    *
    * @param  {DOMNode} node
    *         The node to expand, or null to start from the top.
    */
@@ -1210,17 +1210,17 @@ MarkupView.prototype = {
     if (isOuter) {
       walkerPromise = this.walker.outerHTML(node);
     } else {
       walkerPromise = this.walker.innerHTML(node);
     }
 
     return walkerPromise.then(longstr => {
       return longstr.string().then(html => {
-        longstr.release().then(null, console.error);
+        longstr.release().catch(console.error);
         return html;
       });
     });
   },
 
   /**
    * Retrieve the outerHTML for a remote node.
    *
@@ -1327,17 +1327,17 @@ MarkupView.prototype = {
     let container = this.getContainer(node);
     if (!container) {
       return promise.reject();
     }
 
     // Changing the outerHTML removes the node which outerHTML was changed.
     // Listen to this removal to reselect the right node afterwards.
     this.reselectOnRemoved(node, "outerhtml");
-    return this.walker.setOuterHTML(node, newValue).then(null, () => {
+    return this.walker.setOuterHTML(node, newValue).catch(() => {
       this.cancelReselectOnRemoved();
     });
   },
 
   /**
    * Replace the innerHTML of any node displayed in the inspector with
    * some other HTML code
    * @param  {Node} node
--- a/devtools/client/inspector/markup/views/element-editor.js
+++ b/devtools/client/inspector/markup/views/element-editor.js
@@ -606,17 +606,17 @@ ElementEditor.prototype = {
         newTagName.toLowerCase() === this.node.tagName.toLowerCase() ||
         !("editTagName" in this.markup.walker)) {
       return;
     }
 
     // Changing the tagName removes the node. Make sure the replacing node gets
     // selected afterwards.
     this.markup.reselectOnRemoved(this.node, "edittagname");
-    this.markup.walker.editTagName(this.node, newTagName).then(null, () => {
+    this.markup.walker.editTagName(this.node, newTagName).catch(() => {
       // Failed to edit the tag name, cancel the reselection.
       this.markup.cancelReselectOnRemoved();
     });
   },
 
   destroy: function () {
     for (let key in this.animationTimers) {
       clearTimeout(this.animationTimers[key]);
--- a/devtools/client/inspector/markup/views/text-editor.js
+++ b/devtools/client/inspector/markup/views/text-editor.js
@@ -39,17 +39,17 @@ function TextEditor(container, node, typ
     maxWidth: () => getAutocompleteMaxWidth(this.value, this.container.elt),
     trimOutput: false,
     done: (val, commit) => {
       if (!commit) {
         return;
       }
       this.node.getNodeValue().then(longstr => {
         longstr.string().then(oldValue => {
-          longstr.release().then(null, console.error);
+          longstr.release().catch(console.error);
 
           this.container.undo.do(() => {
             this.node.setNodeValue(val);
           }, () => {
             this.node.setNodeValue(oldValue);
           });
         });
       });
@@ -101,29 +101,29 @@ TextEditor.prototype = {
   },
 
   update: function () {
     let longstr = null;
     this.node.getNodeValue().then(ret => {
       longstr = ret;
       return longstr.string();
     }).then(str => {
-      longstr.release().then(null, console.error);
+      longstr.release().catch(console.error);
       this.value.textContent = str;
 
       let isWhitespace = !/[^\s]/.exec(str);
       this.value.classList.toggle("whitespace", isWhitespace);
 
       let chars = str.replace(/\n/g, "⏎")
                      .replace(/\t/g, "⇥")
                      .replace(/ /g, "◦");
       this.value.setAttribute("title", isWhitespace
         ? INSPECTOR_L10N.getFormatStr("markupView.whitespaceOnly", chars)
         : "");
-    }).then(null, console.error);
+    }).catch(console.error);
   },
 
   destroy: function () {},
 
   /**
    * Stub method for consistency with ElementEditor.
    */
   getInfoAtNode: function () {
--- a/devtools/client/inspector/rules/models/element-style.js
+++ b/devtools/client/inspector/rules/models/element-style.js
@@ -119,17 +119,17 @@ ElementStyle.prototype = {
       // We're done with the previous list of rules.
       for (let r of existingRules) {
         if (r && r.editor) {
           r.editor.destroy();
         }
       }
 
       return undefined;
-    }).then(null, e => {
+    }).catch(e => {
       // populate is often called after a setTimeout,
       // the connection may already be closed.
       if (this.destroyed) {
         return promise.resolve(undefined);
       }
       return promiseWarn(e);
     });
     this.populated = populated;
--- a/devtools/client/inspector/rules/rules.js
+++ b/devtools/client/inspector/rules/rules.js
@@ -773,17 +773,17 @@ CssRuleView.prototype = {
     // engine, we will set properties on a dummy element and observe
     // how their .style attribute reflects them as computed values.
     let dummyElementPromise = promise.resolve(this.styleDocument).then(document => {
       // ::before and ::after do not have a namespaceURI
       let namespaceURI = this.element.namespaceURI ||
           document.documentElement.namespaceURI;
       this._dummyElement = document.createElementNS(namespaceURI,
                                                    this.element.tagName);
-    }).then(null, promiseWarn);
+    }).catch(promiseWarn);
 
     let elementStyle = new ElementStyle(element, this, this.store,
       this.pageStyle, this.showUserAgentStyles);
     this._elementStyle = elementStyle;
 
     this._startSelectingElement();
 
     return dummyElementPromise.then(() => {
@@ -796,17 +796,17 @@ CssRuleView.prototype = {
         if (!refresh) {
           this.element.scrollTop = 0;
         }
         this._stopSelectingElement();
         this._elementStyle.onChanged = () => {
           this._changed();
         };
       }
-    }).then(null, e => {
+    }).catch(e => {
       if (this._elementStyle === elementStyle) {
         this._stopSelectingElement();
         this._clearRules();
       }
       console.error(e);
     });
   },
 
@@ -881,17 +881,17 @@ CssRuleView.prototype = {
       this._clearRules();
       let onEditorsReady = this._createEditors();
       this.refreshPseudoClassPanel();
 
       // Notify anyone that cares that we refreshed.
       return onEditorsReady.then(() => {
         this.emit("ruleview-refreshed");
       }, e => console.error(e));
-    }).then(null, promiseWarn);
+    }).catch(promiseWarn);
   },
 
   /**
    * Show the user that the rule view has no node selected.
    */
   _showEmpty: function () {
     if (this.styleDocument.getElementById("ruleview-no-results")) {
       return;
--- a/devtools/client/inspector/shared/highlighters-overlay.js
+++ b/devtools/client/inspector/shared/highlighters-overlay.js
@@ -326,17 +326,17 @@ HighlightersOverlay.prototype = {
     }
 
     // For some reason, the call to highlighter.hide doesn't always return a
     // promise. This causes some tests to fail when trying to install a
     // rejection handler on the result of the call. To avoid this, check
     // whether the result is truthy before installing the handler.
     let onHidden = this.highlighters[this.hoveredHighlighterShown].hide();
     if (onHidden) {
-      onHidden.then(null, e => console.error(e));
+      onHidden.catch(e => console.error(e));
     }
 
     this.hoveredHighlighterShown = null;
     this.emit("highlighter-hidden");
   },
 
   /**
    * Is the current hovered node a css transform property value in the
--- a/devtools/client/netmonitor/src/har/har-exporter.js
+++ b/devtools/client/netmonitor/src/har/har-exporter.js
@@ -153,17 +153,17 @@ const HarExporter = {
       if (options.jsonp) {
         // This callback name is also used in HAR Viewer by default.
         // http://www.softwareishard.com/har/viewer/
         let callbackName = options.jsonpCallback || "onInputData";
         jsonString = callbackName + "(" + jsonString + ");";
       }
 
       return jsonString;
-    }).then(null, function onError(err) {
+    }).catch(function onError(err) {
       console.error(err);
     });
   },
 
   /**
    * Build HAR data object. This object contains all HTTP data
    * collected by the Network panel. The process is asynchronous
    * since it can involve additional RDP communication (e.g. resolving
--- a/devtools/client/scratchpad/scratchpad.js
+++ b/devtools/client/scratchpad/scratchpad.js
@@ -690,17 +690,17 @@ var Scratchpad = {
     const tabsize = Services.prefs.getIntPref(TAB_SIZE);
 
     return this.prettyPrintWorker.performTask("pretty-print", {
       url: "(scratchpad)",
       indent: tabsize,
       source: uglyText
     }).then(data => {
       this.editor.setText(data.code);
-    }).then(null, error => {
+    }).catch(error => {
       this.writeAsErrorComment({ exception: error });
       throw error;
     });
   },
 
   /**
    * Parse the text and return an AST. If we can't parse it, write an error
    * comment and return false.
@@ -1730,17 +1730,17 @@ var Scratchpad = {
       if (state)
         this.dirty = !state.saved;
 
       this.initialized = true;
       this._triggerObservers("Ready");
       this.populateRecentFilesMenu();
       PreferenceObserver.init();
       CloseObserver.init();
-    }).then(null, (err) => console.error(err));
+    }).catch((err) => console.error(err));
     this._setupCommandListeners();
     this._updateViewMenuItems();
     this._setupPopupShowingListeners();
 
     // Change the accesskey for the help menu as it can be specific on Windows
     // some localizations of Windows (ex:french, german) use "?"
     //  for the help button in the menubar but Gnome does not.
     if (Services.appinfo.OS == "WINNT") {
--- a/devtools/client/scratchpad/test/browser_scratchpad_pprint-02.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_pprint-02.js
@@ -23,17 +23,17 @@ function runTests(sw)
   const space = " ".repeat(6);
 
   const sp = sw.Scratchpad;
   sp.setText("function main() { console.log(5); }");
   sp.prettyPrint().then(() => {
     const prettyText = sp.getText();
     ok(prettyText.includes(space));
     finish();
-  }).then(null, error => {
+  }).catch(error => {
     ok(false, error);
   });
 }
 
 registerCleanupFunction(function () {
   Services.prefs.setIntPref("devtools.editor.tabsize", gTabsize);
   gTabsize = null;
 });
--- a/devtools/client/scratchpad/test/browser_scratchpad_pprint.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_pprint.js
@@ -17,12 +17,12 @@ function test()
 function runTests(sw)
 {
   const sp = sw.Scratchpad;
   sp.setText("function main() { console.log(5); }");
   sp.prettyPrint().then(() => {
     const prettyText = sp.getText();
     ok(prettyText.includes("\n"));
     finish();
-  }).then(null, error => {
+  }).catch(error => {
     ok(false, error);
   });
 }
--- a/devtools/client/shadereditor/panel.js
+++ b/devtools/client/shadereditor/panel.js
@@ -45,17 +45,17 @@ ShaderEditorPanel.prototype = {
         this.panelWin.gFront = new WebGLFront(this.target.client, this.target.form);
         return this.panelWin.startupShaderEditor();
       })
       .then(() => {
         this.isReady = true;
         this.emit("ready");
         return this;
       })
-      .then(null, function onError(aReason) {
+      .catch(function onError(aReason) {
         DevToolsUtils.reportException("ShaderEditorPanel.prototype.open", aReason);
       });
   },
 
   // DevToolPanel API
 
   get target() {
     return this._toolbox.target;
--- a/devtools/client/shadereditor/shadereditor.js
+++ b/devtools/client/shadereditor/shadereditor.js
@@ -308,17 +308,17 @@ var ShadersListView = Heritage.extend(Wi
         vs: vertexShaderText,
         fs: fragmentShaderText
       });
     }
 
     getShaders()
       .then(getSources)
       .then(showSources)
-      .then(null, e => console.error(e));
+      .catch(e => console.error(e));
   },
 
   /**
    * The check listener for the programs container.
    */
   _onProgramCheck: function ({ detail: { checked }, target }) {
     let sourceItem = this.getItemForElement(target);
     let attachment = sourceItem.attachment;
--- a/devtools/client/shadereditor/test/head.js
+++ b/devtools/client/shadereditor/test/head.js
@@ -113,17 +113,17 @@ function ifWebGLSupported() {
 
 function ifWebGLUnsupported() {
   todo(false, "Skipping test because WebGL isn't supported.");
   finish();
 }
 
 function test() {
   let generator = isWebGLSupported(document) ? ifWebGLSupported : ifWebGLUnsupported;
-  Task.spawn(generator).then(null, handleError);
+  Task.spawn(generator).catch(handleError);
 }
 
 function createCanvas() {
   return document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
 }
 
 function once(aTarget, aEventName, aUseCapture = false) {
   info("Waiting for event: '" + aEventName + "' on " + aTarget + ".");
--- a/devtools/client/shared/developer-toolbar.js
+++ b/devtools/client/shared/developer-toolbar.js
@@ -1001,17 +1001,17 @@ OutputPanel.prototype._outputChanged = f
   this.remove();
 
   this.displayedOutput = ev.output;
 
   if (this.displayedOutput.completed) {
     this._update();
   } else {
     this.displayedOutput.promise.then(this._update, this._update)
-                                .then(null, console.error);
+                                .catch(console.error);
   }
 };
 
 /**
  * Called when displayed Output says it's changed or from outputChanged, which
  * happens when there is a new displayed Output.
  */
 OutputPanel.prototype._update = function () {
--- a/devtools/client/shared/redux/middleware/task.js
+++ b/devtools/client/shared/redux/middleware/task.js
@@ -14,17 +14,17 @@ const ERROR_TYPE = exports.ERROR_TYPE = 
  * asynchronously) and yield on each. If called with a promise, calls `dispatch`
  * on the results.
  */
 
 function task({ dispatch, getState }) {
   return next => action => {
     if (isGenerator(action)) {
       return Task.spawn(action.bind(null, dispatch, getState))
-        .then(null, handleError.bind(null, dispatch));
+        .catch(handleError.bind(null, dispatch));
     }
 
     /*
     if (isPromise(action)) {
       return action.then(dispatch, handleError.bind(null, dispatch));
     }
     */
 
--- a/devtools/client/sourceeditor/autocomplete.js
+++ b/devtools/client/sourceeditor/autocomplete.js
@@ -232,17 +232,17 @@ function autoComplete({ ed, cm }) {
     popup.setItems(suggestions);
 
     popup.once("popup-opened", () => {
       // This event is used in tests.
       ed.emit("after-suggest");
     });
     popup.openPopup(cursorElement, -1 * left, 0);
     autocompleteOpts.suggestionInsertedOnce = false;
-  }).then(null, e => console.error(e));
+  }).catch(e => console.error(e));
 }
 
 /**
  * Inserts a popup item into the current cursor location
  * in the editor.
  */
 function insertPopupItem(ed, popupItem) {
   let {preLabel, text} = popupItem;
--- a/devtools/client/styleeditor/StyleEditorUI.jsm
+++ b/devtools/client/styleeditor/StyleEditorUI.jsm
@@ -229,17 +229,17 @@ StyleEditorUI.prototype = {
    * @param {string} event
    *        Event name
    * @param {StyleSheet} styleSheet
    *        StyleSheet object for new sheet
    */
   _onNewDocument: function () {
     this._debuggee.getStyleSheets().then((styleSheets) => {
       return this._resetStyleSheetList(styleSheets);
-    }).then(null, e => console.error(e));
+    }).catch(e => console.error(e));
   },
 
   /**
    * Add editors for all the given stylesheets to the UI.
    *
    * @param  {array} styleSheets
    *         Array of StyleSheetFront
    */
@@ -629,17 +629,17 @@ StyleEditorUI.prototype = {
             let lineCount = editorText.split("\n").length;
             let ruleCount = showEditor.styleSheet.ruleCount;
             if (lineCount >= ruleCount) {
               showEditor.addUnusedRegions(reports);
             } else {
               this.emit("error", { key: "error-compressed", level: "info" });
             }
           }
-        }.bind(this)).then(null, e => console.error(e));
+        }.bind(this)).catch(e => console.error(e));
       }
     });
   },
 
   /**
    * Switch to the editor that has been marked to be selected.
    *
    * @return {Promise}
@@ -919,17 +919,17 @@ StyleEditorUI.prototype = {
         div.appendChild(link);
 
         list.appendChild(div);
       }
 
       sidebar.hidden = !showSidebar || !inSource;
 
       this.emit("media-list-changed", editor);
-    }.bind(this)).then(null, e => console.error(e));
+    }.bind(this)).catch(e => console.error(e));
   },
 
   /**
     * Called when a media condition is clicked
     * If a responsive mode link is clicked, it will launch it.
     *
     * @param {object} e
     *        Event object
--- a/devtools/client/styleeditor/StyleSheetEditor.jsm
+++ b/devtools/client/styleeditor/StyleSheetEditor.jsm
@@ -285,17 +285,17 @@ StyleSheetEditor.prototype = {
    * @return {Promise}
    *         A promise that'll resolve with the source text once the source
    *         has been loaded or reject on unexpected error.
    */
   fetchSource: function () {
     return this._getSourceTextAndPrettify().then((source) => {
       this.sourceLoaded = true;
       return source;
-    }).then(null, e => {
+    }).catch(e => {
       if (this._isDestroyed) {
         console.warn("Could not fetch the source for " +
                      this.styleSheet.href +
                      ", the editor was destroyed");
         console.error(e);
       } else {
         this.emit("error", { key: LOAD_ERROR, append: this.styleSheet.href });
         throw e;
@@ -513,17 +513,17 @@ StyleSheetEditor.prototype = {
     }
     this.focus();
   },
 
   /**
    * Toggled the disabled state of the underlying stylesheet.
    */
   toggleDisabled: function () {
-    this.styleSheet.toggleDisabled().then(null, e => console.error(e));
+    this.styleSheet.toggleDisabled().catch(e => console.error(e));
   },
 
   /**
    * Queue a throttled task to update the live style sheet.
    */
   updateStyleSheet: function () {
     if (this._updateTask) {
       // cancel previous queued task not executed within throttle delay
@@ -555,17 +555,17 @@ StyleSheetEditor.prototype = {
     this._updateTask = null;
 
     if (this.sourceEditor) {
       this._state.text = this.sourceEditor.getText();
     }
 
     this._isUpdating = true;
     this.styleSheet.update(this._state.text, this.transitionsEnabled)
-      .then(null, e => console.error(e));
+      .catch(e => console.error(e));
   },
 
   /**
    * Handle mousemove events, calling _highlightSelectorAt after a delay only
    * and reseting the delay everytime.
    */
   _onMouseMove: function (e) {
     this.highlighter.hide();
--- a/devtools/client/webaudioeditor/panel.js
+++ b/devtools/client/webaudioeditor/panel.js
@@ -39,17 +39,17 @@ WebAudioEditorPanel.prototype = {
         this.panelWin.gFront = new WebAudioFront(this.target.client, this.target.form);
         return this.panelWin.startupWebAudioEditor();
       })
       .then(() => {
         this.isReady = true;
         this.emit("ready");
         return this;
       })
-      .then(null, function onError(aReason) {
+      .catch(function onError(aReason) {
         console.error("WebAudioEditorPanel open failed. " +
                       aReason.error + ": " + aReason.message);
       });
   },
 
   // DevToolPanel API
 
   get target() {
--- a/devtools/client/webconsole/console-output.js
+++ b/devtools/client/webconsole/console-output.js
@@ -3069,17 +3069,17 @@ Widgets.ObjectRenderers.add({
     }
 
     this._text(">");
 
     // Register this widget in the owner message so that it gets destroyed when
     // the message is destroyed.
     this.message.widgets.add(this);
 
-    this.linkToInspector().then(null, e => console.error(e));
+    this.linkToInspector().catch(e => console.error(e));
   },
 
   /**
    * If the DOMNode being rendered can be highlit in the page, this function
    * will attach mouseover/out event listeners to do so, and the inspector icon
    * to open the node in the inspector.
    * @return a promise that resolves when the node has been linked to the
    * inspector, or rejects if it wasn't (either if no toolbox could be found to
@@ -3157,17 +3157,17 @@ Widgets.ObjectRenderers.add({
   /**
    * Unhighlight a previously highlit node
    * @see highlightDomNode
    * @return a promise that resolves when the highlighter has been hidden
    */
   unhighlightDomNode: function () {
     return this.linkToInspector().then(() => {
       return this.toolbox.highlighterUtils.unhighlight();
-    }).then(null, e => console.error(e));
+    }).catch(e => console.error(e));
   },
 
   /**
    * Open the DOMNode corresponding to the ObjectActor in the inspector panel
    * @return a promise that resolves when the inspector has been switched to
    * and the node has been selected, or rejects if the node cannot be selected
    * (detached from the DOM). Note that in any case, the inspector panel will
    * be switched to.
--- a/devtools/client/webconsole/test/browser_console_optimized_out_vars.js
+++ b/devtools/client/webconsole/test/browser_console_optimized_out_vars.js
@@ -45,17 +45,17 @@ function test() {
       webconsole: hud,
       messages: [{
         text: "optimized out",
         category: CATEGORY_OUTPUT,
       }]
     });
 
     finishTest();
-  }).then(null, aError => {
+  }).catch(aError => {
     ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
   });
 }
 
 // Debugger helper functions stolen from devtools/client/debugger/test/head.js.
 
 function ensureThreadClientState(aPanel, aState) {
   let thread = aPanel.panelWin.gThreadClient;
--- a/devtools/client/webconsole/test/browser_webconsole_split.js
+++ b/devtools/client/webconsole/test/browser_webconsole_split.js
@@ -194,17 +194,17 @@ function test() {
   });
 
   function openPanel(toolId) {
     let deferred = promise.defer();
     let target = TargetFactory.forTab(gBrowser.selectedTab);
     gDevTools.showToolbox(target, toolId).then(function (box) {
       toolbox = box;
       deferred.resolve();
-    }).then(null, console.error);
+    }).catch(console.error);
     return deferred.promise;
   }
 
   function openAndCheckPanel(toolId) {
     return openPanel(toolId).then(() => {
       info("Checking toolbox for " + toolId);
       return checkToolboxUI(toolbox.getCurrentPanel());
     });
--- a/devtools/client/webide/content/webide.js
+++ b/devtools/client/webide/content/webide.js
@@ -913,17 +913,17 @@ var Cmds = {
     });
     return UI.busyUntil(disconnecting, "disconnecting from runtime");
   },
 
   takeScreenshot: function () {
     let url = AppManager.deviceFront.screenshotToDataURL();
     return UI.busyUntil(url.then(longstr => {
       return longstr.string().then(dataURL => {
-        longstr.release().then(null, console.error);
+        longstr.release().catch(console.error);
         UI.openInBrowser(dataURL);
       });
     }), "taking screenshot");
   },
 
   showRuntimeDetails: function () {
     UI.selectDeckPanel("runtimedetails");
   },
--- a/devtools/client/webide/modules/app-manager.js
+++ b/devtools/client/webide/modules/app-manager.js
@@ -478,17 +478,17 @@ var AppManager = exports.AppManager = {
         this.connection.on(Connection.Events.CONNECTED, onConnectedOrDisconnected);
         this.connection.on(Connection.Events.DISCONNECTED, onConnectedOrDisconnected);
         try {
           // Reset the connection's state to defaults
           this.connection.resetOptions();
           // Only watch for errors here.  Final resolution occurs above, once
           // we've reached the CONNECTED state.
           this.selectedRuntime.connect(this.connection)
-                              .then(null, e => reject(e));
+                              .catch(e => reject(e));
         } catch (e) {
           reject(e);
         }
       }, reject);
     });
 
     // Record connection result in telemetry
     let logResult = result => {
--- a/devtools/client/webide/test/test_device_preferences.html
+++ b/devtools/client/webide/test/test_device_preferences.html
@@ -72,16 +72,16 @@
 
           searchFields(deck, "debugger");
 
           DebuggerServer.destroy();
 
           yield closeWebIDE(win);
 
           SimpleTest.finish();
-        }).then(null, e => {
+        }).catch(e => {
           ok(false, "Exception: " + e);
           SimpleTest.finish();
         });
       }
     </script>
   </body>
 </html>
--- a/devtools/client/webide/test/test_device_runtime.html
+++ b/devtools/client/webide/test/test_device_runtime.html
@@ -66,16 +66,16 @@
 
           ok(!deck.selectedPanel, "No panel selected");
 
           DebuggerServer.destroy();
 
           yield closeWebIDE(win);
 
           SimpleTest.finish();
-        }).then(null, e => {
+        }).catch(e => {
           ok(false, "Exception: " + e);
           SimpleTest.finish();
         });
       }
     </script>
   </body>
 </html>
--- a/devtools/client/webide/test/test_duplicate_import.html
+++ b/devtools/client/webide/test/test_duplicate_import.html
@@ -61,17 +61,17 @@
           is(items[3].querySelector("span").textContent, "A name (in app directory)", "Panel text is correct");
           is(items[4].querySelector("span").textContent, "hosted manifest name property", "Panel text is correct");
 
           yield closeWebIDE(win);
 
           yield removeAllProjects();
 
           SimpleTest.finish();
-        }).then(null, e => {
+        }).catch(e => {
           ok(false, "Exception: " + e);
           SimpleTest.finish();
         });
       }
     </script>
   </body>
 </html>
 
--- a/devtools/client/webide/test/test_import.html
+++ b/devtools/client/webide/test/test_import.html
@@ -67,16 +67,16 @@
           is(items[3].querySelector("span").textContent, "A name (in app directory)", "Panel text is correct");
           is(items[4].querySelector("span").textContent, "hosted manifest name property", "Panel text is correct");
 
           yield closeWebIDE(win);
 
           yield removeAllProjects();
 
           SimpleTest.finish();
-        }).then(null, e => {
+        }).catch(e => {
           ok(false, "Exception: " + e);
           SimpleTest.finish();
         });
       }
     </script>
   </body>
 </html>
--- a/devtools/server/actors/script.js
+++ b/devtools/server/actors/script.js
@@ -733,17 +733,17 @@ const ThreadActor = ActorClassWithSpec(t
                     }
 
                     packet.frame.where = {
                       source: originalLocation.originalSourceActor.form(),
                       line: originalLocation.originalLine,
                       column: originalLocation.originalColumn
                     };
                     resolve(onPacket(packet))
-          .then(null, error => {
+          .catch(error => {
             reportError(error);
             return {
               error: "unknownError",
               message: error.message + "\n" + error.stack
             };
           })
           .then(pkt => {
             this.conn.send(pkt);
@@ -1066,17 +1066,17 @@ const ThreadActor = ActorClassWithSpec(t
     let needNest = true;
     let eventLoop;
     let returnVal;
 
     p.then((resolvedVal) => {
       needNest = false;
       returnVal = resolvedVal;
     })
-    .then(null, (error) => {
+    .catch((error) => {
       reportError(error, "Error inside unsafeSynchronize:");
     })
     .then(() => {
       if (eventLoop) {
         eventLoop.resolve();
       }
     });
 
--- a/devtools/server/actors/source.js
+++ b/devtools/server/actors/source.js
@@ -154,17 +154,17 @@ let SourceActor = ActorClassWithSpec(sou
     this._encodeAndSetSourceMapURL = this._encodeAndSetSourceMapURL.bind(this);
     this._getSourceText = this._getSourceText.bind(this);
 
     this._mapSourceToAddon();
 
     if (this.threadActor.sources.isPrettyPrinted(this.url)) {
       this._init = this.prettyPrint(
         this.threadActor.sources.prettyPrintIndent(this.url)
-      ).then(null, error => {
+      ).catch(error => {
         DevToolsUtils.reportException("SourceActor", error);
       });
     } else {
       this._init = null;
     }
   },
 
   get isSourceMapped() {
@@ -490,17 +490,17 @@ let SourceActor = ActorClassWithSpec(sou
           };
         }
         return {
           source: createValueGrip(content, this.threadActor.threadLifetimePool,
             this.threadActor.objectGrip),
           contentType: contentType
         };
       })
-      .then(null, error => {
+      .catch(error => {
         reportError(error, "Got an exception during SA_onSource: ");
         throw new Error("Could not load the source for " + this.url + ".\n" +
                         DevToolsUtils.safeErrorString(error));
       });
   },
 
   /**
    * Handler for the "prettyPrint" packet.
@@ -513,17 +513,17 @@ let SourceActor = ActorClassWithSpec(sou
       .then(this._encodeAndSetSourceMapURL)
       .then(() => {
         // We need to reset `_init` now because we have already done the work of
         // pretty printing, and don't want onSource to wait forever for
         // initialization to complete.
         this._init = null;
       })
       .then(this.onSource)
-      .then(null, error => {
+      .catch(error => {
         this.disablePrettyPrint();
         throw new Error(DevToolsUtils.safeErrorString(error));
       });
   },
 
   /**
    * Return a function that sends a request to the pretty print worker, waits on
    * the worker's response, and then returns the pretty printed code.
--- a/devtools/server/actors/utils/TabSources.js
+++ b/devtools/server/actors/utils/TabSources.js
@@ -460,17 +460,17 @@ TabSources.prototype = {
     }
 
     let fetching = fetch(absSourceMapURL, { loadFromCache: false })
       .then(({ content }) => {
         let map = new SourceMapConsumer(content);
         this._setSourceMapRoot(map, absSourceMapURL, sourceURL);
         return map;
       })
-      .then(null, error => {
+      .catch(error => {
         if (!DevToolsUtils.reportingDisabled) {
           DevToolsUtils.reportException("TabSources.prototype._fetchSourceMap", error);
         }
         return null;
       });
     this._sourceMapCache[absSourceMapURL] = fetching;
     return fetching;
   },
--- a/devtools/server/main.js
+++ b/devtools/server/main.js
@@ -1671,17 +1671,17 @@ DebuggerServerConnection.prototype = {
     let pendingResponse = this._actorResponses.get(from) || SyncPromise.resolve(null);
     let responsePromise = pendingResponse.then(() => {
       return responseOrPromise;
     }).then(response => {
       if (!response.from) {
         response.from = from;
       }
       this.transport.send(response);
-    }).then(null, (e) => {
+    }).catch((e) => {
       let errorPacket = this._unknownError(
         "error occurred while processing '" + type, e);
       errorPacket.from = from;
       this.transport.send(errorPacket);
     });
 
     this._actorResponses.set(from, responsePromise);
   },
--- a/devtools/server/tests/mochitest/inspector-helpers.js
+++ b/devtools/server/tests/mochitest/inspector-helpers.js
@@ -202,17 +202,17 @@ function checkAvailable(client, actorID)
     is(response.error, "unrecognizedPacketType",
        "node list actor should be contactable.");
     deferred.resolve(undefined);
   });
   return deferred.promise;
 }
 
 function promiseDone(currentPromise) {
-  currentPromise.then(null, err => {
+  currentPromise.catch(err => {
     ok(false, "Promise failed: " + err);
     if (err.stack) {
       dump(err.stack);
     }
     SimpleTest.finish();
   });
 }
 
@@ -294,17 +294,17 @@ function waitForMutation(walker, test, m
 }
 
 var _tests = [];
 function addTest(test) {
   _tests.push(test);
 }
 
 function addAsyncTest(generator) {
-  _tests.push(() => Task.spawn(generator).then(null, ok.bind(null, false)));
+  _tests.push(() => Task.spawn(generator).catch(ok.bind(null, false)));
 }
 
 function runNextTest() {
   if (_tests.length == 0) {
     SimpleTest.finish();
     return;
   }
   let fn = _tests.shift();
--- a/devtools/server/tests/unit/test_actor-registry-actor.js
+++ b/devtools/server/tests/unit/test_actor-registry-actor.js
@@ -37,17 +37,17 @@ function registerNewActor() {
     constructor: "HelloActor",
     type: { global: true }
   };
 
   gRegistryFront
     .registerActor("resource://test/hello-actor.js", options)
     .then(actorFront => (gActorFront = actorFront))
     .then(talkToNewActor)
-    .then(null, e => {
+    .catch(e => {
       DevToolsUtils.reportException("registerNewActor", e);
       do_check_true(false);
     });
 }
 
 function talkToNewActor() {
   gClient.listTabs(({ helloActor }) => {
     do_check_true(!!helloActor);
@@ -60,17 +60,17 @@ function talkToNewActor() {
     });
   });
 }
 
 function unregisterNewActor() {
   gActorFront
     .unregister()
     .then(testActorIsUnregistered)
-    .then(null, e => {
+    .catch(e => {
       DevToolsUtils.reportException("unregisterNewActor", e);
       do_check_true(false);
     });
 }
 
 function testActorIsUnregistered() {
   gClient.listTabs(({ helloActor }) => {
     do_check_true(!helloActor);
--- a/devtools/server/tests/unit/test_blackboxing-06.js
+++ b/devtools/server/tests/unit/test_blackboxing-06.js
@@ -23,17 +23,17 @@ function run_test() {
       gClient, "test-black-box",
       function (response, tabClient, threadClient) {
         gThreadClient = threadClient;
 
         promise.resolve(setup_code())
           .then(black_box_code)
           .then(run_code)
           .then(test_correct_location)
-          .then(null, function (error) {
+          .catch(function (error) {
             do_check_true(false, "Should not get an error, got " + error);
           })
           .then(function () {
             finishClient(gClient);
           });
       });
   });
   do_test_pending();
--- a/devtools/server/tests/unit/test_promise_state-03.js
+++ b/devtools/server/tests/unit/test_promise_state-03.js
@@ -37,17 +37,17 @@ function run_test() {
 }
 
 function evalCode(debuggee) {
   /* eslint-disable */
   Components.utils.evalInSandbox(
     "doTest();\n" +
     function doTest() {
       var resolved = Promise.reject(new Error("uh oh"));
-      resolved.then(null, () => {
+      resolved.catch(() => {
         var p = resolved;
         debugger;
       });
     },
     debuggee
   );
   /* eslint-enable */
 }
--- a/devtools/server/tests/unit/test_promises_client_getdependentpromises.js
+++ b/devtools/server/tests/unit/test_promises_client_getdependentpromises.js
@@ -18,17 +18,17 @@ add_task(function* () {
 
   ok(Promise.toString().includes("native code"), "Expect native DOM Promise.");
 
   yield testGetDependentPromises(client, chromeActors, () => {
     let p = new Promise(() => {});
     p.name = "p";
     let q = p.then();
     q.name = "q";
-    let r = p.then(null, () => {});
+    let r = p.catch(() => {});
     r.name = "r";
 
     return p;
   });
 
   let response = yield listTabs(client);
   let targetTab = findTab(response.tabs, "test-promises-dependentpromises");
   ok(targetTab, "Found our target tab.");
@@ -37,17 +37,17 @@ add_task(function* () {
   yield testGetDependentPromises(client, targetTab, () => {
     const debuggee =
       DebuggerServer.getTestGlobal("test-promises-dependentpromises");
 
     let p = new debuggee.Promise(() => {});
     p.name = "p";
     let q = p.then();
     q.name = "q";
-    let r = p.then(null, () => {});
+    let r = p.catch(() => {});
     r.name = "r";
 
     return p;
   });
 
   yield close(client);
 });
 
--- a/devtools/server/tests/unit/test_protocol_children.js
+++ b/devtools/server/tests/unit/test_protocol_children.js
@@ -592,14 +592,14 @@ function run_test() {
       do_check_eq(ret.length, 2);
       do_check_true(ret[0] === childFront);
       do_check_true(ret[1] !== childFront);
       do_check_true(ret[1] instanceof ChildFront);
     }).then(() => {
       client.close().then(() => {
         do_test_finished();
       });
-    }).then(null, err => {
+    }).catch(err => {
       do_report_unexpected_exception(err, "Failure executing test");
     });
   });
   do_test_pending();
 }
--- a/devtools/server/tests/unit/test_protocol_longstring.js
+++ b/devtools/server/tests/unit/test_protocol_longstring.js
@@ -230,14 +230,14 @@ function run_test() {
     }).then(() => {
       trace.expectSend({"type": "release", "to": "<actorid>"});
       trace.expectReceive({"from": "<actorid>"});
       expectRootChildren(0);
     }).then(() => {
       client.close().then(() => {
         do_test_finished();
       });
-    }).then(null, err => {
+    }).catch(err => {
       do_report_unexpected_exception(err, "Failure executing test");
     });
   });
   do_test_pending();
 }
--- a/devtools/server/tests/unit/test_protocol_simple.js
+++ b/devtools/server/tests/unit/test_protocol_simple.js
@@ -324,14 +324,14 @@ function run_test() {
         deferred.resolve();
       });
       rootClient.emitFalsyOptions();
       return deferred.promise;
     }).then(() => {
       client.close().then(() => {
         do_test_finished();
       });
-    }).then(null, err => {
+    }).catch(err => {
       do_report_unexpected_exception(err, "Failure executing test");
     });
   });
   do_test_pending();
 }
--- a/devtools/server/tests/unit/test_sourcemaps-10.js
+++ b/devtools/server/tests/unit/test_sourcemaps-10.js
@@ -20,17 +20,17 @@ function run_test() {
   gClient.connect().then(function () {
     attachTestTabAndResume(
       gClient, "test-source-map",
       function (response, tabClient, threadClient) {
         gThreadClient = threadClient;
         promise.resolve(define_code())
           .then(run_code)
           .then(test_frame_location)
-          .then(null, error => {
+          .catch(error => {
             dump(error + "\n");
             dump(error.stack);
             do_check_true(false);
           })
           .then(() => {
             finishClient(gClient);
           });
       });
--- a/devtools/server/tests/unit/test_sourcemaps-11.js
+++ b/devtools/server/tests/unit/test_sourcemaps-11.js
@@ -20,17 +20,17 @@ function run_test() {
   gClient.connect().then(function () {
     attachTestTabAndResume(
       gClient, "test-source-map",
       function (response, tabClient, threadClient) {
         gThreadClient = threadClient;
         promise.resolve(define_code())
           .then(run_code)
           .then(test_frames)
-          .then(null, error => {
+          .catch(error => {
             dump(error + "\n");
             dump(error.stack);
             do_check_true(false);
           })
           .then(() => {
             finishClient(gClient);
           });
       });
--- a/devtools/shared/apps/app-actor-front.js
+++ b/devtools/shared/apps/app-actor-front.js
@@ -615,17 +615,17 @@ AppActorFront.prototype = {
     // On demand, retrieve apps icons in order to be able
     // to synchronously retrieve it on `App` objects
     let promises = [];
     for (let [, app] of this._apps) {
       promises.push(app.getIcon());
     }
 
     return DevToolsUtils.settleAll(promises)
-                        .then(null, () => {});
+                        .catch(() => {});
   },
 
   _listenAppEvents: function (listener) {
     this._listeners.push(listener);
 
     if (this._listeners.length > 1) {
       return promise.resolve();
     }
--- a/devtools/shared/fronts/device.js
+++ b/devtools/shared/fronts/device.js
@@ -14,17 +14,17 @@ const DeviceFront = protocol.FrontClassW
     this.actorID = form.deviceActor;
     this.manage(this);
   },
 
   screenshotToBlob: function () {
     return this.screenshotToDataURL().then(longstr => {
       return longstr.string().then(dataURL => {
         let deferred = defer();
-        longstr.release().then(null, Cu.reportError);
+        longstr.release().catch(Cu.reportError);
         let req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
             .createInstance(Ci.nsIXMLHttpRequest);
         req.open("GET", dataURL, true);
         req.responseType = "blob";
         req.onload = () => {
           deferred.resolve(req.response);
         };
         req.onerror = () => {
--- a/devtools/shared/gcli/templater.js
+++ b/devtools/shared/gcli/templater.js
@@ -169,17 +169,17 @@ function processNode(state, node, data) 
             if (value.indexOf("${") === 0 &&
                 value.charAt(value.length - 1) === "}") {
               replacement = envEval(state, value.slice(2, -1), data, value);
               if (replacement && typeof replacement.then === "function") {
                 node.setAttribute(name, "");
                 /* jshint loopfunc:true */
                 replacement.then(function (newValue) {
                   node.setAttribute(name, newValue);
-                }).then(null, console.error);
+                }).catch(console.error);
               } else {
                 if (state.options.blankNullUndefined && replacement == null) {
                   replacement = "";
                 }
                 node.setAttribute(name, replacement);
               }
             } else {
               node.setAttribute(name, processString(state, value, data));
@@ -448,17 +448,17 @@ function handleAsync(thing, siblingNode,
     // Placeholder element to be replaced once we have the real data
     let tempNode = siblingNode.ownerDocument.createElement("span");
     siblingNode.parentNode.insertBefore(tempNode, siblingNode);
     thing.then(function (delayed) {
       inserter(delayed, tempNode);
       if (tempNode.parentNode != null) {
         tempNode.remove();
       }
-    }).then(null, function (error) {
+    }).catch(function (error) {
       console.error(error.stack);
     });
   } else {
     inserter(thing, siblingNode);
   }
 }
 
 /**
--- a/devtools/shared/protocol.js
+++ b/devtools/shared/protocol.js
@@ -1107,17 +1107,17 @@ var generateRequestHandlers = function (
 
           conn.send(response);
         };
 
         this._queueResponse(p => {
           return p
             .then(() => ret)
             .then(sendReturn)
-            .then(null, this.writeError.bind(this));
+            .catch(this.writeError.bind(this));
         });
       } catch (e) {
         this._queueResponse(p => {
           return p.then(() => this.writeError(e));
         });
       }
     };
 
@@ -1246,17 +1246,17 @@ var Front = Class({
    */
   send: function (packet) {
     if (packet.to) {
       this.conn._transport.send(packet);
     } else {
       this.actor().then(actorID => {
         packet.to = actorID;
         this.conn._transport.send(packet);
-      }).then(null, e => console.error(e));
+      }).catch(e => console.error(e));
     }
   },
 
   /**
    * Send a two-way request on the connection.
    */
   request: function (packet) {
     let deferred = defer();
--- a/devtools/shared/tests/mochitest/test_eventemitter_basic.html
+++ b/devtools/shared/tests/mochitest/test_eventemitter_basic.html
@@ -28,17 +28,17 @@
       const { Task } = require("devtools/shared/task");
 
       SimpleTest.waitForExplicitFinish();
 
       testEmitter();
       testEmitter({});
 
       Task.spawn(testPromise)
-          .then(null, ok.bind(null, false))
+          .catch(ok.bind(null, false))
           .then(SimpleTest.finish);
 
       function testEmitter(aObject) {
         let emitter;
 
         if (aObject) {
           emitter = aObject;
           EventEmitter.decorate(emitter);
--- a/devtools/shared/tests/unit/test_async-utils.js
+++ b/devtools/shared/tests/unit/test_async-utils.js
@@ -21,17 +21,17 @@ function run_test() {
   Task.spawn(function* () {
     yield test_async_args(asyncOnce);
     yield test_async_return(asyncOnce);
     yield test_async_throw(asyncOnce);
 
     yield test_async_once();
     yield test_async_invoke();
     do_test_finished();
-  }).then(null, error => {
+  }).catch(error => {
     do_throw(error);
   });
 }
 
 // Test that arguments are correctly passed through to the async function.
 function test_async_args(async) {
   let obj = {
     method: async(function* (a, b) {
@@ -61,17 +61,17 @@ function test_async_return(async) {
 // Test that the throwing from an async function rejects the promise.
 function test_async_throw(async) {
   let obj = {
     method: async(function* () {
       throw new Error("boom");
     })
   };
 
-  return obj.method().then(null, error => {
+  return obj.method().catch(error => {
     do_check_true(error instanceof Error);
     do_check_eq(error.message, "boom");
   });
 }
 
 // Test that asyncOnce only runs the async function once per instance and
 // returns the same promise for that instance.
 function test_async_once() {
@@ -144,14 +144,14 @@ function test_async_invoke() {
     do_check_eq(results[0], "foo");
     do_check_eq(results[1], "bar");
 
     // Test throwing from the function.
     function thrower() {
       throw new Error("boom");
     }
 
-    yield promiseCall(thrower).then(null, error => {
+    yield promiseCall(thrower).catch(error => {
       do_check_true(error instanceof Error);
       do_check_eq(error.message, "boom");
     });
   });
 }
--- a/devtools/shared/transport/tests/unit/test_client_server_bulk.js
+++ b/devtools/shared/transport/tests/unit/test_client_server_bulk.js
@@ -172,17 +172,17 @@ var test_bulk_request_cs = Task.async(fu
     // Send bulk data to server
     request.on("bulk-send-ready", bulkSendReadyCallback);
 
     // Set up reply handling for this type
     replyHandlers[replyType](request).then(() => {
       client.close();
       transport.close();
     });
-  }).then(null, do_throw);
+  }).catch(do_throw);
 
   DebuggerServer.on("connectionchange", (event, type) => {
     if (type === "closed") {
       serverDeferred.resolve();
     }
   });
 
   return promise.all([
@@ -214,17 +214,17 @@ var test_json_request_cs = Task.async(fu
       type: actorType
     });
 
     // Set up reply handling for this type
     replyHandlers[replyType](request).then(() => {
       client.close();
       transport.close();
     });
-  }).then(null, do_throw);
+  }).catch(do_throw);
 
   DebuggerServer.on("connectionchange", (event, type) => {
     if (type === "closed") {
       serverDeferred.resolve();
     }
   });
 
   return promise.all([
--- a/dom/crypto/test/test_WebCrypto.html
+++ b/dom/crypto/test/test_WebCrypto.html
@@ -486,19 +486,17 @@ TestArray.addTest(
     function encrypt(x, iv) {
       return crypto.subtle.encrypt(
         { name: "AES-CBC", iv: iv },
         x, tv.aes_cbc_enc.data);
     }
 
     function doEncrypt(x) {
       return encrypt(x, new Uint8Array(15))
-        .then(
-          null,
-          function () { return encrypt(new Uint8Array(17)); }
+        .catch(function () { return encrypt(new Uint8Array(17)); }
         );
     }
 
     crypto.subtle.importKey("raw", tv.aes_cbc_enc.key, "AES-CBC", false, ['encrypt'])
       .then(doEncrypt)
       .then(
         error(that),
         complete(that)
@@ -536,19 +534,17 @@ TestArray.addTest(
     function decrypt(x, iv) {
       return crypto.subtle.decrypt(
         { name: "AES-CBC", iv: iv },
         x, tv.aes_cbc_dec.data);
     }
 
     function doDecrypt(x) {
       return decrypt(x, new Uint8Array(15))
-        .then(
-          null,
-          function () { return decrypt(x, new Uint8Array(17)); }
+        .catch(function () { return decrypt(x, new Uint8Array(17)); }
         );
     }
 
     crypto.subtle.importKey("raw", tv.aes_cbc_dec.key, "AES-CBC", false, ['decrypt'])
       .then(doDecrypt)
       .then(
         error(that),
         complete(that)
@@ -586,19 +582,17 @@ TestArray.addTest(
     function encrypt(x, iv) {
       return crypto.subtle.encrypt(
         { name: "AES-CTR", counter: iv, length: 32 },
         x, tv.aes_ctr_enc.data);
     }
 
     function doEncrypt(x) {
       return encrypt(x, new Uint8Array(15))
-        .then(
-          null,
-          function () { return encrypt(x, new Uint8Array(17)); }
+        .catch(function () { return encrypt(x, new Uint8Array(17)); }
         );
     }
 
     crypto.subtle.importKey("raw", tv.aes_ctr_enc.key, "AES-CTR", false, ['encrypt'])
       .then(doEncrypt)
       .then(
         error(that),
         complete(that)
@@ -636,19 +630,17 @@ TestArray.addTest(
     function doDecrypt(x, iv) {
       return crypto.subtle.decrypt(
         { name: "AES-CTR", counter: iv, length: 32 },
         x, tv.aes_ctr_dec.data);
     }
 
     function decrypt(x) {
       return decrypt(x, new Uint8Array(15))
-        .then(
-          null,
-          function () { return decrypt(x, new Uint8Array(17)); }
+        .catch(function () { return decrypt(x, new Uint8Array(17)); }
         );
     }
 
     crypto.subtle.importKey("raw", tv.aes_ctr_dec.key, "AES-CTR", false, ['decrypt'])
       .then(doDecrypt)
       .then(
         error(that),
         complete(that)
--- a/dom/promise/tests/test_on_promise_settled.html
+++ b/dom/promise/tests/test_on_promise_settled.html
@@ -38,17 +38,17 @@ Debugger.prototype.onPromiseResolved.
 
   var promise = Promise.resolve();
   promise
     .then(function () {
       ok(wrappedPromise);
       is(wrappedPromise.unsafeDereference(), promise);
       dbg.onPromiseSettled = undefined;
     })
-    .then(null, function (e) {
+    .catch(function (e) {
       ok(false, "Got an unexpected error: " + e);
     })
     .then(SimpleTest.finish);
   </script>
 </pre>
 </body>
 </html>
 
--- a/dom/promise/tests/test_on_promise_settled_duplicates.html
+++ b/dom/promise/tests/test_on_promise_settled_duplicates.html
@@ -43,17 +43,17 @@ Bug 1084065 - Test that Debugger.prototy
     fulfill(2);
     fulfill(3);
   });
 
   promise
     .then(function () {
       dbg.onPromiseSettled = undefined;
     })
-    .then(null, function (e) {
+    .catch(function (e) {
       ok(false, "Got an unexpected error: " + e);
     })
     .then(SimpleTest.finish);
   </script>
 </pre>
 </body>
 </html>
 
--- a/dom/promise/tests/unit/test_monitor_uncaught.js
+++ b/dom/promise/tests/unit/test_monitor_uncaught.js
@@ -15,17 +15,17 @@ PromiseTestUtils.disableUncaughtRejectio
 add_task(function* test_globals() {
   Assert.equal(Promise.defer || undefined, undefined, "We are testing DOM Promise.");
   Assert.notEqual(PromiseDebugging, undefined, "PromiseDebugging is available.");
 });
 
 add_task(function* test_promiseID() {
   let p1 = new Promise(resolve => {});
   let p2 = new Promise(resolve => {});
-  let p3 = p2.then(null, null);
+  let p3 = p2.catch(null);
   let promise = [p1, p2, p3];
 
   let identifiers = promise.map(PromiseDebugging.getPromiseID);
   do_print("Identifiers: " + JSON.stringify(identifiers));
   let idSet = new Set(identifiers);
   Assert.equal(idSet.size, identifiers.length,
     "PromiseDebugging.getPromiseID returns a distinct id per promise");
 
@@ -97,37 +97,37 @@ add_task(function* test_observe_uncaught
       promise: Promise.resolve(0),
       name: "Promise.resolve",
     };
     yield {
       promise: Promise.resolve(resolve => resolve(0)),
       name: "Resolution callback",
     };
     yield {
-      promise: Promise.resolve(0).then(null, null),
+      promise: Promise.resolve(0).catch(null),
       name: "`then(null, null)`"
     };
     yield {
-      promise: Promise.reject(0).then(null, () => {}),
+      promise: Promise.reject(0).catch(() => {}),
       name: "Reject and catch immediately",
     };
     yield {
       promise: resolveLater(),
       name: "Resolve later",
     };
     yield {
       promise: Promise.reject("Simple rejection"),
       leftUncaught: true,
       consumed: false,
       name: "Promise.reject",
     };
 
     // Reject a promise now, consume it later.
     let p = Promise.reject("Reject now, consume later");
-    setTimeout(() => p.then(null, () => {
+    setTimeout(() => p.catch(() => {
       do_print("Consumed promise");
     }), 200);
     yield {
       promise: p,
       leftUncaught: true,
       consumed: true,
       name: "Reject now, consume later",
     };
--- a/dom/security/test/csp/file_service_worker.html
+++ b/dom/security/test/csp/file_service_worker.html
@@ -8,12 +8,12 @@
   function finish(status) {
     window.parent.postMessage({result: status}, "*");
   }
 
   navigator.serviceWorker.ready.then(finish.bind(null, 'allowed'),
                                      finish.bind(null, 'blocked'));
   navigator.serviceWorker
            .register("file_service_worker.js", {scope: "."})
-           .then(null, finish.bind(null, 'blocked'));
+           .catch(finish.bind(null, 'blocked'));
   </script>
 </body>
 </html>
--- a/mobile/android/chrome/content/aboutDownloads.js
+++ b/mobile/android/chrome/content/aboutDownloads.js
@@ -14,18 +14,18 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, "PluralForm", "resource://gre/modules/PluralForm.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Services", "resource://gre/modules/Services.jsm");
 
 var gStrings = Services.strings.createBundle("chrome://browser/locale/aboutDownloads.properties");
 XPCOMUtils.defineLazyGetter(this, "strings",
                             () => Services.strings.createBundle("chrome://browser/locale/aboutDownloads.properties"));
 
 function deleteDownload(download) {
-  download.finalize(true).then(null, Cu.reportError);
-  OS.File.remove(download.target.path).then(null, ex => {
+  download.finalize(true).catch(Cu.reportError);
+  OS.File.remove(download.target.path).catch(ex => {
     if (!(ex instanceof OS.File.Error && ex.becauseNoSuchFile)) {
       Cu.reportError(ex);
     }
   });
 }
 
 var contextMenu = {
   _items: [],
@@ -34,41 +34,41 @@ var contextMenu = {
   init: function () {
     let element = document.getElementById("downloadmenu");
     element.addEventListener("click",
                              event => event.download = this._targetDownload,
                              true);
     this._items = [
       new ContextMenuItem("open",
                           download => download.succeeded,
-                          download => download.launch().then(null, Cu.reportError)),
+                          download => download.launch().catch(Cu.reportError)),
       new ContextMenuItem("retry",
                           download => download.error ||
                                       (download.canceled && !download.hasPartialData),
-                          download => download.start().then(null, Cu.reportError)),
+                          download => download.start().catch(Cu.reportError)),
       new ContextMenuItem("remove",
                           download => download.stopped,
                           download => {
                             Downloads.getList(Downloads.ALL)
                                      .then(list => list.remove(download))
-                                     .then(null, Cu.reportError);
+                                     .catch(Cu.reportError);
                             deleteDownload(download);
                           }),
       new ContextMenuItem("pause",
                           download => !download.stopped && download.hasPartialData,
-                          download => download.cancel().then(null, Cu.reportError)),
+                          download => download.cancel().catch(Cu.reportError)),
       new ContextMenuItem("resume",
                           download => download.canceled && download.hasPartialData,
-                          download => download.start().then(null, Cu.reportError)),
+                          download => download.start().catch(Cu.reportError)),
       new ContextMenuItem("cancel",
                           download => !download.stopped ||
                                       (download.canceled && download.hasPartialData),
                           download => {
-                            download.cancel().then(null, Cu.reportError);
-                            download.removePartialData().then(null, Cu.reportError);
+                            download.cancel().catch(Cu.reportError);
+                            download.removePartialData().catch(Cu.reportError);
                           }),
       // following menu item is a global action
       new ContextMenuItem("removeall",
                           () => downloadLists.finished.length > 0,
                           () => downloadLists.removeFinished())
     ];
   },
 
@@ -111,22 +111,22 @@ ContextMenuItem.prototype = {
 function DownloadListView(type, listElementId) {
   this.listElement = document.getElementById(listElementId);
   contextMenu.addContextMenuEventListener(this.listElement);
 
   this.items = new Map();
 
   Downloads.getList(type)
            .then(list => list.addView(this))
-           .then(null, Cu.reportError);
+           .catch(Cu.reportError);
 
   window.addEventListener("unload", event => {
     Downloads.getList(type)
              .then(list => list.removeView(this))
-             .then(null, Cu.reportError);
+             .catch(Cu.reportError);
   });
 }
 
 DownloadListView.prototype = {
   get finished() {
     let finished = [];
     for (let download of this.items.keys()) {
       if (download.stopped && (!download.hasPartialData || download.error)) {
@@ -210,17 +210,17 @@ var downloadLists = {
     let title = strings.GetStringFromName("downloadAction.deleteAll");
     let messageForm = strings.GetStringFromName("downloadMessage.deleteAll");
     let message = PluralForm.get(finished.length, messageForm).replace("#1", finished.length);
 
     if (Services.prompt.confirm(null, title, message)) {
       Downloads.getList(Downloads.ALL)
                .then(list => {
                  for (let download of finished) {
-                   list.remove(download).then(null, Cu.reportError);
+                   list.remove(download).catch(Cu.reportError);
                    deleteDownload(download);
                  }
                }, Cu.reportError);
     }
   }
 };
 
 function DownloadItem(download) {
@@ -301,17 +301,17 @@ DownloadItem.prototype = {
     element.querySelector(".icon").src = this.iconUrl;
     element.querySelector(".size").textContent = this.size;
     element.querySelector(".state").textContent = this.stateDescription;
     element.querySelector(".title").setAttribute("value", this.fileName);
   },
 
   onClick: function (event) {
     if (this.download.succeeded) {
-      this.download.launch().then(null, Cu.reportError);
+      this.download.launch().catch(Cu.reportError);
     }
   },
 
   onDownloadChanged: function () {
     this._updateFromDownload();
     this.updateElement(this.element);
   },
 
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -6839,17 +6839,17 @@ var Distribution = {
       let bytes = yield OS.File.read(aFile.path);
       let raw = new TextDecoder().decode(bytes) || "";
 
       try {
         aCallback(JSON.parse(raw));
       } catch (e) {
         Cu.reportError("Distribution: Could not parse JSON: " + e);
       }
-    }).then(null, function onError(reason) {
+    }).catch(function onError(reason) {
       if (!(reason instanceof OS.File.Error && reason.becauseNoSuchFile)) {
         Cu.reportError("Distribution: Could not read from " + aFile.leafName + " file");
       }
     });
   },
 
   // Track pending installs so we can avoid showing notifications for them.
   pendingAddonInstalls: new Set(),
--- a/mobile/android/components/AddonUpdateService.js
+++ b/mobile/android/components/AddonUpdateService.js
@@ -54,17 +54,17 @@ AddonUpdateService.prototype = {
 
     // If we already auto-upgraded and installed new versions, ignore this check
     if (gNeedsRestart)
       return;
 
     AddonManagerPrivate.backgroundUpdateCheck();
 
     let gmp = new GMPInstallManager();
-    gmp.simpleCheckAndInstall().then(null, () => {});
+    gmp.simpleCheckAndInstall().catch(() => {});
 
     let interval = 1000 * getPref("getIntPref", PREF_ADDON_UPDATE_INTERVAL, 86400);
     EventDispatcher.instance.sendRequest({
       type: "Gecko:ScheduleRun",
       action: "update-addons",
       trigger: interval,
       interval: interval,
     });
--- a/mobile/android/components/Snippets.js
+++ b/mobile/android/components/Snippets.js
@@ -135,17 +135,17 @@ function updateSnippets() {
 /**
  * Caches snippets server response text to `snippets.json` in profile directory.
  *
  * @param response responseText returned from snippets server
  */
 function cacheSnippets(response) {
   let data = gEncoder.encode(response);
   let promise = OS.File.writeAtomic(gSnippetsPath, data, { tmpPath: gSnippetsPath + ".tmp" });
-  promise.then(null, e => Cu.reportError("Error caching snippets: " + e));
+  promise.catch(e => Cu.reportError("Error caching snippets: " + e));
 }
 
 /**
  * Loads snippets from cached `snippets.json`.
  */
 function loadSnippetsFromCache() {
   let promise = OS.File.read(gSnippetsPath);
   promise.then(array => {
@@ -264,17 +264,17 @@ function writeStat(snippetId, timestamp)
         yield file.write(data);
       } finally {
         yield file.close();
       }
     } catch (ex if ex instanceof OS.File.Error && ex.becauseNoSuchFile) {
       // If the file doesn't exist yet, create it.
       yield OS.File.writeAtomic(gStatsPath, data, { tmpPath: gStatsPath + ".tmp" });
     }
-  }).then(null, e => Cu.reportError("Error writing snippets stats: " + e));
+  }).catch(e => Cu.reportError("Error writing snippets stats: " + e));
 }
 
 /**
  * Reads snippets stats data from `snippets-stats.txt` and sends the data to metrics.
  */
 function sendStats() {
   let promise = OS.File.read(gStatsPath);
   promise.then(array => sendStatsRequest(gDecoder.decode(array)), e => {
@@ -310,17 +310,17 @@ function sendStatsRequest(data) {
   _httpGetRequest(url, removeStats);
 }
 
 /**
  * Removes text file where we store snippets stats.
  */
 function removeStats() {
   let promise = OS.File.remove(gStatsPath);
-  promise.then(null, e => Cu.reportError("Error removing snippets stats: " + e));
+  promise.catch(e => Cu.reportError("Error removing snippets stats: " + e));
 }
 
 /**
  * Helper function to make HTTP GET requests.
  *
  * @param url where we send the request
  * @param callback function that is called with the xhr responseText
  */
--- a/netwerk/protocol/http/UserAgentUpdates.jsm
+++ b/netwerk/protocol/http/UserAgentUpdates.jsm
@@ -137,18 +137,18 @@ this.UserAgentUpdates = {
           let update = JSON.parse(gDecoder.decode(bytes));
           if (!update) {
             throw new Error("invalid update");
           }
           return update;
         }
       );
       // try to load next one if the previous load failed
-      return prevLoad ? prevLoad.then(null, tryNext) : tryNext();
-    }, null).then(null, (ex) => {
+      return prevLoad ? prevLoad.catch(tryNext) : tryNext();
+    }, null).catch((ex) => {
       if (AppConstants.platform !== "android") {
         // All previous (non-Android) load attempts have failed, so we bail.
         throw new Error("UserAgentUpdates: Failed to load " + FILE_UPDATES +
                          ex + "\n" + ex.stack);
       }
       // Make one last attempt to read from the Fennec APK root.
       return readChannel("resource://android/" + FILE_UPDATES);
     }).then((update) => {
--- a/netwerk/test/mochitests/test_user_agent_updates.html
+++ b/netwerk/test/mochitests/test_user_agent_updates.html
@@ -272,17 +272,17 @@ const chromeScript = SpecialPowers.loadC
               OVERRIDES.forEach(function (val) {
                 val.expected && is(overrides[val.domain], val.expected,
                   'Incorrect saved override: ' + val.override);
               });
               sendAsyncMessage("testProfileSaveDone");
             }
           );
         }
-      ).then(null,
+      ).catch(
         (reason) => {
           throw reason
         }
       );
     })();
   }
 
   function testProfileLoad(hostname) {
--- a/security/manager/ssl/tests/mochitest/mixedcontent/test_bug383369.html
+++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug383369.html
@@ -53,17 +53,17 @@
             list.removeView(this);
             aDownload.whenSucceeded().then(() => {
               list.removeFinished();
               sendAsyncMessage("navigate", "bug383369step2.html");
             });
           },
         });
         sendAsyncMessage("navigate", "download.auto");
-      }).then(null, Cu.reportError);
+      }).catch(Cu.reportError);
     });
     script.addMessageListener("navigate", function(url) {
       window.location = url;
     });
   }
 
   function afterNavigationTest() {}
 
--- a/services/fxaccounts/FxAccounts.jsm
+++ b/services/fxaccounts/FxAccounts.jsm
@@ -1175,17 +1175,17 @@ FxAccountsInternal.prototype = {
       // were already polling for receipt of an earlier email.
       this.pollStartDate = Date.now();
       if (!currentState.whenVerifiedDeferred) {
         currentState.whenVerifiedDeferred = PromiseUtils.defer();
         // This deferred might not end up with any handlers (eg, if sync
         // is yet to start up.)  This might cause "A promise chain failed to
         // handle a rejection" messages, so add an error handler directly
         // on the promise to log the error.
-        currentState.whenVerifiedDeferred.promise.then(null, err => {
+        currentState.whenVerifiedDeferred.promise.catch(err => {
           log.info("the wait for user verification was stopped: " + err);
         });
       }
     }
 
     // We return a promise for testing only. Other callers can ignore this,
     // since verification polling continues in the background.
     return this.checkEmailStatus(sessionToken, { reason: why })
--- a/services/fxaccounts/tests/xpcshell/test_accounts.js
+++ b/services/fxaccounts/tests/xpcshell/test_accounts.js
@@ -647,18 +647,17 @@ add_test(function test_fetchAndUnwrapKey
       run_next_test();
     });
   });
 
   fxa.setSignedInUser(user).then(
     user2 => {
       return fxa.internal.fetchAndUnwrapKeys();
     }
-  ).then(
-    null,
+  ).catch(
     error => {
       log.info("setSignedInUser correctly rejected");
     }
   )
 });
 
 // Alice (User A) signs up but never verifies her email.  Then Bob (User B)
 // signs in with a verified email.  Ensure that no sign-in events are triggered
@@ -1221,67 +1220,67 @@ add_task(function* test_getOAuthTokenCac
   do_check_eq(result, "token");
 });
 
 Services.prefs.setCharPref("identity.fxaccounts.remote.oauth.uri", "https://example.com/v1");
 add_test(function test_getOAuthToken_invalid_param() {
   let fxa = new MockFxAccounts();
 
   fxa.getOAuthToken()
-    .then(null, err => {
+    .catch(err => {
        do_check_eq(err.message, "INVALID_PARAMETER");
        fxa.signOut().then(run_next_test);
     });
 });
 
 add_test(function test_getOAuthToken_invalid_scope_array() {
   let fxa = new MockFxAccounts();
 
   fxa.getOAuthToken({scope: []})
-    .then(null, err => {
+    .catch(err => {
        do_check_eq(err.message, "INVALID_PARAMETER");
        fxa.signOut().then(run_next_test);
     });
 });
 
 add_test(function test_getOAuthToken_misconfigure_oauth_uri() {
   let fxa = new MockFxAccounts();
 
   Services.prefs.deleteBranch("identity.fxaccounts.remote.oauth.uri");
 
   fxa.getOAuthToken()
-    .then(null, err => {
+    .catch(err => {
        do_check_eq(err.message, "INVALID_PARAMETER");
        // revert the pref
        Services.prefs.setCharPref("identity.fxaccounts.remote.oauth.uri", "https://example.com/v1");
        fxa.signOut().then(run_next_test);
     });
 });
 
 add_test(function test_getOAuthToken_no_account() {
   let fxa = new MockFxAccounts();
 
   fxa.internal.currentAccountState.getUserAccountData = function() {
     return Promise.resolve(null);
   };
 
   fxa.getOAuthToken({ scope: "profile" })
-    .then(null, err => {
+    .catch(err => {
        do_check_eq(err.message, "NO_ACCOUNT");
        fxa.signOut().then(run_next_test);
     });
 });
 
 add_test(function test_getOAuthToken_unverified() {
   let fxa = new MockFxAccounts();
   let alice = getTestUser("alice");
 
   fxa.setSignedInUser(alice).then(() => {
     fxa.getOAuthToken({ scope: "profile" })
-      .then(null, err => {
+      .catch(err => {
          do_check_eq(err.message, "UNVERIFIED_ACCOUNT");
          fxa.signOut().then(run_next_test);
       });
   });
 });
 
 add_test(function test_getOAuthToken_network_error() {
   let fxa = new MockFxAccounts();
@@ -1299,17 +1298,17 @@ add_test(function test_getOAuthToken_net
     return Promise.reject(new FxAccountsOAuthGrantClientError({
       error: ERROR_NETWORK,
       errno: ERRNO_NETWORK
     }));
   };
 
   fxa.setSignedInUser(alice).then(() => {
     fxa.getOAuthToken({ scope: "profile", client })
-      .then(null, err => {
+      .catch(err => {
          do_check_eq(err.message, "NETWORK_ERROR");
          do_check_eq(err.details.errno, ERRNO_NETWORK);
          run_next_test();
       });
   });
 });
 
 add_test(function test_getOAuthToken_auth_error() {
@@ -1328,17 +1327,17 @@ add_test(function test_getOAuthToken_aut
     return Promise.reject(new FxAccountsOAuthGrantClientError({
       error: ERROR_INVALID_FXA_ASSERTION,
       errno: ERRNO_INVALID_FXA_ASSERTION
     }));
   };
 
   fxa.setSignedInUser(alice).then(() => {
     fxa.getOAuthToken({ scope: "profile", client })
-      .then(null, err => {
+      .catch(err => {
          do_check_eq(err.message, "AUTH_ERROR");
          do_check_eq(err.details.errno, ERRNO_INVALID_FXA_ASSERTION);
          run_next_test();
       });
   });
 });
 
 add_test(function test_getOAuthToken_unknown_error() {
@@ -1354,17 +1353,17 @@ add_test(function test_getOAuthToken_unk
     client_id: "abc123"
   });
   client.getTokenFromAssertion = function() {
     return Promise.reject("boom");
   };
 
   fxa.setSignedInUser(alice).then(() => {
     fxa.getOAuthToken({ scope: "profile", client })
-      .then(null, err => {
+      .catch(err => {
          do_check_eq(err.message, "UNKNOWN_ERROR");
          run_next_test();
       });
   });
 });
 
 add_test(function test_getSignedInUserProfile() {
   let alice = getTestUser("alice");
--- a/services/fxaccounts/tests/xpcshell/test_oauth_grant_client.js
+++ b/services/fxaccounts/tests/xpcshell/test_oauth_grant_client.js
@@ -100,19 +100,17 @@ add_test(function parseErrorResponse() {
   let response = {
     success: true,
     status: STATUS_SUCCESS,
     body: "unexpected",
   };
 
   client._Request = new mockResponse(response);
   client.getTokenFromAssertion("assertion", "scope")
-    .then(
-      null,
-      function(e) {
+    .catch(function(e) {
         do_check_eq(e.name, "FxAccountsOAuthGrantClientError");
         do_check_eq(e.code, STATUS_SUCCESS);
         do_check_eq(e.errno, ERRNO_PARSE);
         do_check_eq(e.error, ERROR_PARSE);
         do_check_eq(e.message, "unexpected");
         run_next_test();
       }
     );
@@ -122,19 +120,17 @@ add_test(function serverErrorResponse() 
   let client = new FxAccountsOAuthGrantClient(CLIENT_OPTIONS);
   let response = {
     status: 400,
     body: "{ \"code\": 400, \"errno\": 104, \"error\": \"Bad Request\", \"message\": \"Unauthorized\", \"reason\": \"Invalid fxa assertion\" }",
   };
 
   client._Request = new mockResponse(response);
   client.getTokenFromAssertion("blah", "scope")
-    .then(
-    null,
-    function(e) {
+    .catch(function(e) {
       do_check_eq(e.name, "FxAccountsOAuthGrantClientError");
       do_check_eq(e.code, 400);
       do_check_eq(e.errno, ERRNO_INVALID_FXA_ASSERTION);
       do_check_eq(e.error, "Bad Request");
       do_check_eq(e.message, "Unauthorized");
       run_next_test();
     }
   );
@@ -142,53 +138,47 @@ add_test(function serverErrorResponse() 
 
 add_test(function networkErrorResponse() {
   let client = new FxAccountsOAuthGrantClient({
     serverURL: "http://domain.dummy",
     client_id: "abc123"
   });
   Services.prefs.setBoolPref("identity.fxaccounts.skipDeviceRegistration", true);
   client.getTokenFromAssertion("assertion", "scope")
-    .then(
-      null,
-      function(e) {
+    .catch(function(e) {
         do_check_eq(e.name, "FxAccountsOAuthGrantClientError");
         do_check_eq(e.code, null);
         do_check_eq(e.errno, ERRNO_NETWORK);
         do_check_eq(e.error, ERROR_NETWORK);
         run_next_test();
       }
     ).catch(() => {}).then(() =>
       Services.prefs.clearUserPref("identity.fxaccounts.skipDeviceRegistration"));
 });
 
 add_test(function unsupportedMethod() {
   let client = new FxAccountsOAuthGrantClient(CLIENT_OPTIONS);
 
   return client._createRequest("/", "PUT")
-    .then(
-      null,
-      function(e) {
+    .catch(function(e) {
         do_check_eq(e.name, "FxAccountsOAuthGrantClientError");
         do_check_eq(e.code, ERROR_CODE_METHOD_NOT_ALLOWED);
         do_check_eq(e.errno, ERRNO_NETWORK);
         do_check_eq(e.error, ERROR_NETWORK);
         do_check_eq(e.message, ERROR_MSG_METHOD_NOT_ALLOWED);
         run_next_test();
       }
     );
 });
 
 add_test(function onCompleteRequestError() {
   let client = new FxAccountsOAuthGrantClient(CLIENT_OPTIONS);
   client._Request = new mockResponseError(new Error("onComplete error"));
   client.getTokenFromAssertion("assertion", "scope")
-    .then(
-      null,
-      function(e) {
+    .catch(function(e) {
         do_check_eq(e.name, "FxAccountsOAuthGrantClientError");
         do_check_eq(e.code, null);
         do_check_eq(e.errno, ERRNO_NETWORK);
         do_check_eq(e.error, ERROR_NETWORK);
         do_check_eq(e.message, "Error: onComplete error");
         run_next_test();
       }
   );
@@ -198,19 +188,17 @@ add_test(function incorrectErrno() {
   let client = new FxAccountsOAuthGrantClient(CLIENT_OPTIONS);
   let response = {
     status: 400,
     body: "{ \"code\": 400, \"errno\": \"bad errno\", \"error\": \"Bad Request\", \"message\": \"Unauthorized\", \"reason\": \"Invalid fxa assertion\" }",
   };
 
   client._Request = new mockResponse(response);
   client.getTokenFromAssertion("blah", "scope")
-    .then(
-    null,
-    function(e) {
+    .catch(function(e) {
       do_check_eq(e.name, "FxAccountsOAuthGrantClientError");
       do_check_eq(e.code, 400);
       do_check_eq(e.errno, ERRNO_UNKNOWN_ERROR);
       do_check_eq(e.error, "Bad Request");
       do_check_eq(e.message, "Unauthorized");
       run_next_test();
     }
   );
--- a/services/fxaccounts/tests/xpcshell/test_profile_client.js
+++ b/services/fxaccounts/tests/xpcshell/test_profile_client.js
@@ -135,19 +135,17 @@ add_test(function parseErrorResponse() {
   let response = {
     success: true,
     status: STATUS_SUCCESS,
     body: "unexpected",
   };
 
   client._Request = new mockResponse(response);
   client.fetchProfile()
-    .then(
-      null,
-      function(e) {
+    .catch(function(e) {
         do_check_eq(e.name, "FxAccountsProfileClientError");
         do_check_eq(e.code, STATUS_SUCCESS);
         do_check_eq(e.errno, ERRNO_PARSE);
         do_check_eq(e.error, ERROR_PARSE);
         do_check_eq(e.message, "unexpected");
         run_next_test();
       }
     );
@@ -157,19 +155,17 @@ add_test(function serverErrorResponse() 
   let client = new FxAccountsProfileClient(PROFILE_OPTIONS);
   let response = {
     status: 500,
     body: "{ \"code\": 500, \"errno\": 100, \"error\": \"Bad Request\", \"message\": \"Something went wrong\", \"reason\": \"Because the internet\" }",
   };
 
   client._Request = new mockResponse(response);
   client.fetchProfile()
-    .then(
-    null,
-    function(e) {
+    .catch(function(e) {
       do_check_eq(e.name, "FxAccountsProfileClientError");
       do_check_eq(e.code, 500);
       do_check_eq(e.errno, 100);
       do_check_eq(e.error, "Bad Request");
       do_check_eq(e.message, "Something went wrong");
       run_next_test();
     }
   );
@@ -293,19 +289,17 @@ add_test(function server401ResponsePersi
       get() {
         this.response = response;
         ++numRequests;
         this.onComplete();
       }
     };
   }
 
-  client.fetchProfile().then(
-    null,
-    function(e) {
+  client.fetchProfile().catch(function(e) {
       do_check_eq(e.name, "FxAccountsProfileClientError");
       do_check_eq(e.code, 401);
       do_check_eq(e.errno, 100);
       do_check_eq(e.error, "It's not your token, it's you!");
       // should have been exactly 2 requests and exactly 2 auth headers.
       do_check_eq(numRequests, 2);
       do_check_eq(numAuthHeaders, 2);
       // and we should have seen both tokens revoked.
@@ -316,52 +310,46 @@ add_test(function server401ResponsePersi
 });
 
 add_test(function networkErrorResponse() {
   let client = new FxAccountsProfileClient({
     serverURL: "http://domain.dummy",
     fxa: mockFxa,
   });
   client.fetchProfile()
-    .then(
-      null,
-      function(e) {
+    .catch(function(e) {
         do_check_eq(e.name, "FxAccountsProfileClientError");
         do_check_eq(e.code, null);
         do_check_eq(e.errno, ERRNO_NETWORK);
         do_check_eq(e.error, ERROR_NETWORK);
         run_next_test();
       }
     );
 });
 
 add_test(function unsupportedMethod() {
   let client = new FxAccountsProfileClient(PROFILE_OPTIONS);
 
   return client._createRequest("/profile", "PUT")
-    .then(
-      null,
-      function(e) {
+    .catch(function(e) {
         do_check_eq(e.name, "FxAccountsProfileClientError");
         do_check_eq(e.code, ERROR_CODE_METHOD_NOT_ALLOWED);
         do_check_eq(e.errno, ERRNO_NETWORK);
         do_check_eq(e.error, ERROR_NETWORK);
         do_check_eq(e.message, ERROR_MSG_METHOD_NOT_ALLOWED);
         run_next_test();
       }
     );
 });
 
 add_test(function onCompleteRequestError() {
   let client = new FxAccountsProfileClient(PROFILE_OPTIONS);
   client._Request = new mockResponseError(new Error("onComplete error"));
   client.fetchProfile()
-    .then(
-      null,
-      function(e) {
+    .catch(function(e) {
         do_check_eq(e.name, "FxAccountsProfileClientError");
         do_check_eq(e.code, null);
         do_check_eq(e.errno, ERRNO_NETWORK);
         do_check_eq(e.error, ERROR_NETWORK);
         do_check_eq(e.message, "Error: onComplete error");
         run_next_test();
       }
   );
--- a/services/sync/modules/browserid_identity.js
+++ b/services/sync/modules/browserid_identity.js
@@ -835,18 +835,17 @@ BrowserIDClusterManager.prototype = {
         }
       ).then(endPointFromIdentityToken
       );
     };
 
     let cb = Async.makeSpinningCallback();
     promiseClusterURL().then(function(clusterURL) {
       cb(null, clusterURL);
-    }).then(
-      null, err => {
+    }).catch(err => {
       log.info("Failed to fetch the cluster URL", err);
       // service.js's verifyLogin() method will attempt to fetch a cluster
       // URL when it sees a 401.  If it gets null, it treats it as a "real"
       // auth error and sets Status.login to LOGIN_FAILED_LOGIN_REJECTED, which
       // in turn causes a notification bar to appear informing the user they
       // need to re-authenticate.
       // On the other hand, if fetching the cluster URL fails with an exception,
       // verifyLogin() assumes it is a transient error, and thus doesn't show
--- a/services/sync/modules/engines/history.js
+++ b/services/sync/modules/engines/history.js
@@ -263,17 +263,17 @@ HistoryStore.prototype = {
     let i, k;
     for (i = 0, k = 0; i < records.length; i++) {
       let record = records[k] = records[i];
       let shouldApply;
 
       try {
         if (record.deleted) {
           let promise = this.remove(record);
-          promise = promise.then(null, ex => failed.push(record.id));
+          promise = promise.catch(ex => failed.push(record.id));
           blockers.push(promise);
 
           // No further processing needed. Remove it from the list.
           shouldApply = false;
         } else {
           shouldApply = this._recordToPlaceInfo(record);
         }
       } catch (ex) {
--- a/services/sync/tps/extensions/tps/resource/modules/bookmarks.jsm
+++ b/services/sync/tps/extensions/tps/resource/modules/bookmarks.jsm
@@ -20,17 +20,17 @@ Cu.import("resource://services-common/as
 Cu.import("resource://tps/logger.jsm");
 
 var DumpBookmarks = function TPS_Bookmarks__DumpBookmarks() {
   let cb = Async.makeSpinningCallback();
   PlacesBackups.getBookmarksTree().then(result => {
     let [bookmarks, ] = result;
     Logger.logInfo("Dumping Bookmarks...\n" + JSON.stringify(bookmarks) + "\n\n");
     cb(null);
-  }).then(null, error => {
+  }).catch(error => {
     cb(error);
   });
   cb.wait();
 };
 
 /**
  * extend, causes a child object to inherit from a parent
  */
--- a/testing/modules/Assert.jsm
+++ b/testing/modules/Assert.jsm
@@ -387,17 +387,17 @@ proto.rejects = function(promise, expect
       err => {
         if (expected && !expectedException(err, expected)) {
           reject(err);
           return;
         }
         this.report(false, err, expected, message);
         resolve();
       }
-    ).then(null, reject);
+    ).catch(reject);
   });
 };
 
 function compareNumbers(expression, lhs, rhs, message, operator) {
   let lhsIsNumber = typeof lhs == "number";
   let rhsIsNumber = typeof rhs == "number";
 
   if (lhsIsNumber && rhsIsNumber) {
--- a/toolkit/components/asyncshutdown/AsyncShutdown.jsm
+++ b/toolkit/components/asyncshutdown/AsyncShutdown.jsm
@@ -706,17 +706,17 @@ function Barrier(name) {
       } else {
         // If `condition` is not a function, `trigger` is not particularly
         // interesting, and `condition` needs to be normalized to a promise.
         trigger = () => {};
         promise = Promise.resolve(condition);
       }
 
       // Make sure that `promise` never rejects.
-      promise = promise.then(null, error => {
+      promise = promise.catch(error => {
         let msg = `A blocker encountered an error while we were waiting.
           Blocker:  ${ name }
           Phase: ${ this._name }
           State: ${ safeGetState(fetchState) }`;
         warn(msg, error);
 
         // The error should remain uncaught, to ensure that it
         // still causes tests to fail.
@@ -847,17 +847,17 @@ Barrier.prototype = Object.freeze({
       blocker.trigger(); // We have guarantees that this method will never throw
     }
 
     this._isStarted = true;
 
     // Now, wait
     let promise = this._waitForMe.wait();
 
-    promise = promise.then(null, function onError(error) {
+    promise = promise.catch(function onError(error) {
       // I don't think that this can happen.
       // However, let's be overcautious with async/shutdown error reporting.
       let msg = "An uncaught error appeared while completing the phase." +
         " Phase: " + topic;
       warn(msg, error);
     });
 
     promise = promise.then(() => {
--- a/toolkit/components/jsdownloads/src/DownloadCore.jsm
+++ b/toolkit/components/jsdownloads/src/DownloadCore.jsm
@@ -569,17 +569,17 @@ this.Download.prototype = {
    * @rejects  JavaScript exception if any of the operations failed.
    */
   async _succeed() {
     await DownloadIntegration.downloadDone(this);
 
     this._deferSucceeded.resolve();
 
     if (this.launchWhenSucceeded) {
-      this.launch().then(null, Cu.reportError);
+      this.launch().catch(Cu.reportError);
 
       // Always schedule files to be deleted at the end of the private browsing
       // mode, regardless of the value of the pref.
       if (this.source.isPrivate) {
         gExternalAppLauncher.deleteTemporaryPrivateFileWhenPossible(
                              new FileUtils.File(this.target.path));
       } else if (Services.prefs.getBoolPref(
                   "browser.helperApps.deleteTempFileOnExit")) {
@@ -954,17 +954,17 @@ this.Download.prototype = {
           }
 
           this.hasBlockedData = false;
           this.hasPartialData = false;
         }
 
         this._notifyChange();
       }
-    })().then(null, Cu.reportError);
+    })().catch(Cu.reportError);
   },
 
   /**
    * True if the "finalize" method has been called.  This prevents the download
    * from starting again after having been stopped.
    */
   _finalized: false,
 
--- a/toolkit/components/jsdownloads/src/DownloadIntegration.jsm
+++ b/toolkit/components/jsdownloads/src/DownloadIntegration.jsm
@@ -909,17 +909,17 @@ this.DownloadObserver = {
       onDownloadRemoved: aDownload => {
         downloadsSet.delete(aDownload);
         // The download must also be removed from the canceled when offline set.
         this._canceledOfflineDownloads.delete(aDownload);
       }
     };
 
     // We register the view asynchronously.
-    aList.addView(downloadsView).then(null, Cu.reportError);
+    aList.addView(downloadsView).catch(Cu.reportError);
   },
 
   /**
    * Wrapper that handles the test mode before calling the prompt that display
    * a warning message box that informs that there are active downloads,
    * and asks whether the user wants to cancel them or not.
    *
    * @param aCancel
@@ -982,18 +982,18 @@ this.DownloadObserver = {
         break;
       case "last-pb-context-exited":
         let promise = (async function() {
           let list = await Downloads.getList(Downloads.PRIVATE);
           let downloads = await list.getAll();
 
           // We can remove the downloads and finalize them in parallel.
           for (let download of downloads) {
-            list.remove(download).then(null, Cu.reportError);
-            download.finalize(true).then(null, Cu.reportError);
+            list.remove(download).catch(Cu.reportError);
+            download.finalize(true).catch(Cu.reportError);
           }
         })();
         // Handle test mode
         if (gCombinedDownloadIntegration._testResolveClearPrivateList) {
           gCombinedDownloadIntegration._testResolveClearPrivateList(promise);
         } else {
           promise.catch(ex => Cu.reportError(ex));
         }
--- a/toolkit/components/jsdownloads/src/DownloadLegacy.js
+++ b/toolkit/components/jsdownloads/src/DownloadLegacy.js
@@ -127,31 +127,31 @@ DownloadLegacyTransfer.prototype = {
             this._cancelable.cancel(Cr.NS_ERROR_ABORT);
             if (this._cancelable instanceof Ci.nsIWebBrowserPersist) {
               // This component will not send the STATE_STOP notification.
               download.saver.onTransferFinished(Cr.NS_ERROR_ABORT);
               this._cancelable = null;
             }
           }
         });
-      }).then(null, Cu.reportError);
+      }).catch(Cu.reportError);
     } else if ((aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) &&
         (aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK)) {
       // The last file has been received, or the download failed.  Wait for the
       // associated Download object to be available before notifying.
       this._deferDownload.promise.then(download => {
         // At this point, the hash has been set and we need to copy it to the
         // DownloadSaver.
         if (Components.isSuccessCode(aStatus)) {
           download.saver.setSha256Hash(this._sha256Hash);
           download.saver.setSignatureInfo(this._signatureInfo);
           download.saver.setRedirects(this._redirects);
         }
         download.saver.onTransferFinished(aStatus);
-      }).then(null, Cu.reportError);
+      }).catch(Cu.reportError);
 
       // Release the reference to the component executing the download.
       this._cancelable = null;
     }
   },
 
   onProgressChange: function DLT_onProgressChange(aWebProgress, aRequest,
                                                   aCurSelfProgress,
@@ -171,33 +171,33 @@ DownloadLegacyTransfer.prototype = {
     // change, but if no network request actually started, it is possible that
     // we only receive a status change with an error status code.
     if (!Components.isSuccessCode(aStatus)) {
       this._componentFailed = true;
 
       // Wait for the associated Download object to be available.
       this._deferDownload.promise.then(function DLT_OSC_onDownload(aDownload) {
         aDownload.saver.onTransferFinished(aStatus);
-      }).then(null, Cu.reportError);
+      }).catch(Cu.reportError);
     }
   },
 
   onSecurityChange() { },
 
   // nsIWebProgressListener2
 
   onProgressChange64: function DLT_onProgressChange64(aWebProgress, aRequest,
                                                       aCurSelfProgress,
                                                       aMaxSelfProgress,
                                                       aCurTotalProgress,
                                                       aMaxTotalProgress) {
     // Wait for the associated Download object to be available.
     this._deferDownload.promise.then(function DLT_OPC64_onDownload(aDownload) {
       aDownload.saver.onProgressBytes(aCurTotalProgress, aMaxTotalProgress);
-    }).then(null, Cu.reportError);
+    }).catch(Cu.reportError);
   },
 
   onRefreshAttempted: function DLT_onRefreshAttempted(aWebProgress, aRefreshURI,
                                                       aMillis, aSameURI) {
     // Indicate that refreshes and redirects are allowed by default.  However,
     // note that download components don't usually call this method at all.
     return true;
   },
@@ -242,17 +242,17 @@ DownloadLegacyTransfer.prototype = {
       // Start the download before allowing it to be controlled.  Ignore errors.
       aDownload.start().catch(() => {});
 
       // Start processing all the other events received through nsITransfer.
       this._deferDownload.resolve(aDownload);
 
       // Add the download to the list, allowing it to be seen and canceled.
       return Downloads.getList(Downloads.ALL).then(list => list.add(aDownload));
-    }).then(null, Cu.reportError);
+    }).catch(Cu.reportError);
   },
 
   setSha256Hash(hash) {
     this._sha256Hash = hash;
   },
 
   setSignatureInfo(signatureInfo) {
     this._signatureInfo = signatureInfo;
--- a/toolkit/components/jsdownloads/src/DownloadList.jsm
+++ b/toolkit/components/jsdownloads/src/DownloadList.jsm
@@ -236,20 +236,20 @@ this.DownloadList.prototype = {
             (!aFilterFn || aFilterFn(download))) {
           // Remove the download first, so that the views don't get the change
           // notifications that may occur during finalization.
           await this.remove(download);
           // Ensure that the download is stopped and no partial data is kept.
           // This works even if the download state has changed meanwhile.  We
           // don't need to wait for the procedure to be complete before
           // processing the other downloads in the list.
-          download.finalize(true).then(null, Cu.reportError);
+          download.finalize(true).catch(Cu.reportError);
         }
       }
-    })().then(null, Cu.reportError);
+    })().catch(Cu.reportError);
   },
 };
 
 // DownloadCombinedList
 
 /**
  * Provides a unified, unordered list combining public and private downloads.
  *
@@ -261,18 +261,18 @@ this.DownloadList.prototype = {
  *        Underlying DownloadList containing public downloads.
  * @param aPrivateList
  *        Underlying DownloadList containing private downloads.
  */
 this.DownloadCombinedList = function(aPublicList, aPrivateList) {
   DownloadList.call(this);
   this._publicList = aPublicList;
   this._privateList = aPrivateList;
-  aPublicList.addView(this).then(null, Cu.reportError);
-  aPrivateList.addView(this).then(null, Cu.reportError);
+  aPublicList.addView(this).catch(Cu.reportError);
+  aPrivateList.addView(this).catch(Cu.reportError);
 }
 
 this.DownloadCombinedList.prototype = {
   __proto__: DownloadList.prototype,
 
   /**
    * Underlying DownloadList containing public downloads.
    */
--- a/toolkit/components/jsdownloads/test/unit/head.js
+++ b/toolkit/components/jsdownloads/test/unit/head.js
@@ -331,40 +331,40 @@ function promiseStartLegacyDownload(aSou
 
   return new Promise(resolve => {
 
     Downloads.getList(Downloads.ALL).then(function(aList) {
       // Temporarily register a view that will get notified when the download we
       // are controlling becomes visible in the list of downloads.
       aList.addView({
         onDownloadAdded(aDownload) {
-          aList.removeView(this).then(null, do_report_unexpected_exception);
+          aList.removeView(this).catch(do_report_unexpected_exception);
 
           // Remove the download to keep the list empty for the next test.  This
           // also allows the caller to register the "onchange" event directly.
           let promise = aList.remove(aDownload);
 
           // When the download object is ready, make it available to the caller.
           promise.then(() => resolve(aDownload),
                        do_report_unexpected_exception);
         },
-      }).then(null, do_report_unexpected_exception);
+      }).catch(do_report_unexpected_exception);
 
       let isPrivate = aOptions && aOptions.isPrivate;
 
       // Initialize the components so they reference each other.  This will cause
       // the Download object to be created and added to the public downloads.
       transfer.init(sourceURI, NetUtil.newURI(targetFile), null, mimeInfo, null,
                     null, persist, isPrivate);
       persist.progressListener = transfer;
 
       // Start the actual download process.
       persist.savePrivacyAwareURI(sourceURI, null, null, 0, null, null, targetFile,
                                   isPrivate);
-    }).then(null, do_report_unexpected_exception);
+    }).catch(do_report_unexpected_exception);
 
   });
 }
 
 /**
  * Starts a new download using the nsIHelperAppService interface, and controls
  * it using the legacy nsITransfer interface.  The source of the download will
  * be "interruptible_resumable.txt" and partially downloaded data will be kept.
@@ -384,27 +384,27 @@ function promiseStartExternalHelperAppSe
 
   return new Promise(resolve => {
 
     Downloads.getList(Downloads.PUBLIC).then(function(aList) {
       // Temporarily register a view that will get notified when the download we
       // are controlling becomes visible in the list of downloads.
       aList.addView({
         onDownloadAdded(aDownload) {
-          aList.removeView(this).then(null, do_report_unexpected_exception);
+          aList.removeView(this).catch(do_report_unexpected_exception);
 
           // Remove the download to keep the list empty for the next test.  This
           // also allows the caller to register the "onchange" event directly.
           let promise = aList.remove(aDownload);
 
           // When the download object is ready, make it available to the caller.
           promise.then(() => resolve(aDownload),
                        do_report_unexpected_exception);
         },
-      }).then(null, do_report_unexpected_exception);
+      }).catch(do_report_unexpected_exception);
 
       let channel = NetUtil.newChannel({
         uri: sourceURI,
         loadUsingSystemPrincipal: true
       });
 
       // Start the actual download process.
       channel.asyncOpen2({
@@ -422,17 +422,17 @@ function promiseStartExternalHelperAppSe
         },
 
         onDataAvailable(aRequest, aContext, aInputStream, aOffset,
                                   aCount) {
           this.contentListener.onDataAvailable(aRequest, aContext, aInputStream,
                                                aOffset, aCount);
         },
       });
-    }).then(null, do_report_unexpected_exception);
+    }).catch(do_report_unexpected_exception);
 
   });
 }
 
 /**
  * Waits for a download to reach half of its progress, in case it has not
  * reached the expected progress already.
  *
@@ -634,17 +634,17 @@ function registerInterruptibleHandler(aP
     aResponse.processAsync();
     aFirstPartFn(aRequest, aResponse);
 
     // Wait on the current deferred object, then finish the request.
     _gDeferResponses.promise.then(function RIH_onSuccess() {
       aSecondPartFn(aRequest, aResponse);
       aResponse.finish();
       do_print("Interruptible request finished.");
-    }).then(null, Cu.reportError);
+    }).catch(Cu.reportError);
   });
 }
 
 /**
  * Ensure the given date object is valid.
  *
  * @param aDate
  *        The date object to be checked. This value can be null.
--- a/toolkit/components/osfile/modules/osfile_async_front.jsm
+++ b/toolkit/components/osfile/modules/osfile_async_front.jsm
@@ -369,19 +369,19 @@ var Scheduler = this.Scheduler = {
    * This function will be executed once all the previously
    * pushed tasks have completed.
    * @return {Promise} A promise with the same behavior as
    * the promise returned by |code|.
    */
   push: function(code) {
     let promise = this.queue.then(code);
     // By definition, |this.queue| can never reject.
-    this.queue = promise.then(null, () => undefined);
+    this.queue = promise.catch(() => undefined);
     // Fork |promise| to ensure that uncaught errors are reported
-    return promise.then(null, null);
+    return promise.catch(null);
   },
 
   /**
    * Post a message to the worker thread.
    *
    * @param {string} method The name of the method to call.
    * @param {...} args The arguments to pass to the method. These arguments
    * must be clonable.
--- a/toolkit/components/passwordmgr/LoginManagerContent.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerContent.jsm
@@ -441,17 +441,17 @@ var LoginManagerContent = {
     messageManager.sendAsyncMessage("LoginStats:LoginEncountered");
 
     if (!gEnabled) {
       return;
     }
 
     this._getLoginDataFromParent(form, { showMasterPassword: true })
         .then(this.loginsFound.bind(this))
-        .then(null, Cu.reportError);
+        .catch(Cu.reportError);
   },
 
   onPageShow(event, window) {
     this._detectInsecureFormLikes(window);
   },
 
   /**
    * Maps all DOM content documents in this content process, including those in
@@ -645,17 +645,17 @@ var LoginManagerContent = {
       this._getLoginDataFromParent(acForm, { showMasterPassword: false })
           .then(({ form, loginsFound, recipes }) => {
             this._fillForm(form, loginsFound, recipes, {
               autofillForm: true,
               clobberPassword: true,
               userTriggered: true,
             });
           })
-          .then(null, Cu.reportError);
+          .catch(Cu.reportError);
     } else {
       // Ignore the event, it's for some input we don't care about.
     }
   },
 
   /**
    * @param {FormLike} form - the FormLike to look for password fields in.
    * @param {Object} options
--- a/toolkit/components/passwordmgr/nsLoginManager.js
+++ b/toolkit/components/passwordmgr/nsLoginManager.js
@@ -522,17 +522,17 @@ LoginManager.prototype = {
       previousResult = null;
     }
 
     let rect = BrowserUtils.getElementBoundingScreenRect(aElement);
     let acLookupPromise = this._autoCompleteLookupPromise =
       LoginManagerContent._autoCompleteSearchAsync(aSearchString, previousResult,
                                                    aElement, rect);
     acLookupPromise.then(completeSearch.bind(this, acLookupPromise))
-                             .then(null, Cu.reportError);
+                             .catch(Cu.reportError);
   },
 
   stopSearch() {
     this._autoCompleteLookupPromise = null;
   },
 }; // end of LoginManager implementation
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([LoginManager]);
--- a/toolkit/components/places/Bookmarks.jsm
+++ b/toolkit/components/places/Bookmarks.jsm
@@ -715,17 +715,17 @@ var Bookmarks = Object.freeze({
                                         syncChangeCounter = syncChangeCounter + :syncChangeDelta
                WHERE id IN (SELECT id FROM moz_bookmarks WHERE guid = :folderGuid )
               `, { folderGuid, time, syncChangeDelta });
           }
         });
 
         // We don't wait for the frecency calculation.
         if (urls && urls.length) {
-          updateFrecency(db, urls, true).then(null, Cu.reportError);
+          updateFrecency(db, urls, true).catch(Cu.reportError);
         }
       }
     );
   },
 
   /**
    * Returns a list of recently bookmarked items.
    * Only includes actual bookmarks. Excludes folders, separators and queries.
--- a/toolkit/components/places/PlacesUtils.jsm
+++ b/toolkit/components/places/PlacesUtils.jsm
@@ -3064,17 +3064,17 @@ PlacesCreateLivemarkTransaction.prototyp
         }
       }, Cu.reportError);
   },
 
   undoTransaction: function CLTXN_undoTransaction() {
     // The getLivemark callback may fail, but it is used just to serialize,
     // so it doesn't matter.
     this._promise = PlacesUtils.livemarks.getLivemark({ id: this.item.id })
-      .then(null, null).then( () => {
+      .catch(null).then( () => {
         PlacesUtils.bookmarks.removeItem(this.item.id);
       });
   }
 };
 
 
 /**
  * Transaction for removing a livemark item.
@@ -3116,17 +3116,17 @@ PlacesRemoveLivemarkTransaction.prototyp
   },
 
   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 })
-      .then(null, () => {
+      .catch(() => {
         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
                                           }).then(
           aLivemark => {
--- a/toolkit/components/places/UnifiedComplete.js
+++ b/toolkit/components/places/UnifiedComplete.js
@@ -2199,17 +2199,17 @@ UnifiedComplete.prototype = {
         // indices.  A larger cache helps reducing IO and improving performance.
         // The value used here is larger than the default Storage value defined
         // as MAX_CACHE_SIZE_BYTES in storage/mozStorageConnection.cpp.
         await conn.execute("PRAGMA cache_size = -6144"); // 6MiB
 
         await SwitchToTabStorage.initDatabase(conn);
 
         return conn;
-      })().then(null, ex => {
+      })().catch(ex => {
         dump("Couldn't get database handle: " + ex + "\n");
         Cu.reportError(ex);
       });
     }
     return this._promiseDatabase;
   },
 
   // mozIPlacesAutoComplete
@@ -2251,17 +2251,17 @@ UnifiedComplete.prototype = {
     // result regardless, so we still create the Search object.
     if (!Prefs.enabled) {
       this.finishSearch(true);
       return;
     }
 
     let search = this._currentSearch;
     this.getDatabaseHandle().then(conn => search.execute(conn))
-                            .then(null, ex => {
+                            .catch(ex => {
                               dump(`Query failed: ${ex}\n`);
                               Cu.reportError(ex);
                             })
                             .then(() => {
                               if (search == this._currentSearch) {
                                 this.finishSearch(true);
                               }
                             });
--- a/toolkit/components/places/tests/unit/test_bookmarks_restore_notification.js
+++ b/toolkit/components/places/tests/unit/test_bookmarks_restore_notification.js
@@ -209,17 +209,17 @@ add_task(async function test_html_restor
 
   do_print("HTML restore: normal restore should succeed");
   let file = await promiseFile("bookmarks-test_restoreNotification.html");
   await addBookmarks();
   await BookmarkHTMLUtils.exportToFile(file);
   await PlacesUtils.bookmarks.eraseEverything();
   try {
     BookmarkHTMLUtils.importFromFile(file, false)
-                     .then(null, do_report_unexpected_exception);
+                     .catch(do_report_unexpected_exception);
   } catch (e) {
     do_throw("  Restore should not have failed");
   }
 
   await checkObservers(expectPromises, expectedData);
   await teardown(file);
 });
 
@@ -229,17 +229,17 @@ add_task(async function test_html_restor
     folderId:   null
   }
   let expectPromises = registerObservers(true);
 
   do_print("HTML restore: empty file should succeed");
   let file = await promiseFile("bookmarks-test_restoreNotification.init.html");
   try {
     BookmarkHTMLUtils.importFromFile(file, false)
-                     .then(null, do_report_unexpected_exception);
+                     .catch(do_report_unexpected_exception);
   } catch (e) {
     do_throw("  Restore should not have failed");
   }
 
   await checkObservers(expectPromises, expectedData);
   await teardown(file);
 });
 
@@ -271,17 +271,17 @@ add_task(async function test_html_init_r
 
   do_print("HTML initial restore: normal restore should succeed");
   let file = await promiseFile("bookmarks-test_restoreNotification.init.html");
   await addBookmarks();
   await BookmarkHTMLUtils.exportToFile(file);
   await PlacesUtils.bookmarks.eraseEverything();
   try {
     BookmarkHTMLUtils.importFromFile(file, true)
-                     .then(null, do_report_unexpected_exception);
+                     .catch(do_report_unexpected_exception);
   } catch (e) {
     do_throw("  Restore should not have failed");
   }
 
   await checkObservers(expectPromises, expectedData);
   await teardown(file);
 });
 
@@ -291,17 +291,17 @@ add_task(async function test_html_init_r
     folderId:   null
   }
   let expectPromises = registerObservers(true);
 
   do_print("HTML initial restore: empty file should succeed");
   let file = await promiseFile("bookmarks-test_restoreNotification.init.html");
   try {
     BookmarkHTMLUtils.importFromFile(file, true)
-                     .then(null, do_report_unexpected_exception);
+                     .catch(do_report_unexpected_exception);
   } catch (e) {
     do_throw("  Restore should not have failed");
   }
 
   await checkObservers(expectPromises, expectedData);
   await teardown(file);
 });
 
--- a/toolkit/components/thumbnails/PageThumbs.jsm
+++ b/toolkit/components/thumbnails/PageThumbs.jsm
@@ -529,19 +529,17 @@ this.PageThumbsStorage = {
 
   ensurePath: function Storage_ensurePath() {
     // Create the directory (ignore any error if the directory
     // already exists). As all writes are done from the PageThumbsWorker
     // thread, which serializes its operations, this ensures that
     // future operations can proceed without having to check whether
     // the directory exists.
     return PageThumbsWorker.post("makeDir",
-      [this.path, {ignoreExisting: true}]).then(
-        null,
-        function onError(aReason) {
+      [this.path, {ignoreExisting: true}]).catch(function onError(aReason) {
           Components.utils.reportError("Could not create thumbnails directory" + aReason);
         });
   },
 
   getLeafNameForURL: function Storage_getLeafNameForURL(aURL) {
     if (typeof aURL != "string") {
       throw new TypeError("Expecting a string");
     }
--- a/toolkit/content/contentAreaUtils.js
+++ b/toolkit/content/contentAreaUtils.js
@@ -427,17 +427,17 @@ function internalSave(aURL, aDocument, a
     promiseTargetFile(fpParams, aSkipPrompt, relatedURI).then(aDialogAccepted => {
       if (!aDialogAccepted)
         return;
 
       saveAsType = fpParams.saveAsType;
       file = fpParams.file;
 
       continueSave();
-    }).then(null, Components.utils.reportError);
+    }).catch(Components.utils.reportError);
   }
 
   function continueSave() {
     // XXX We depend on the following holding true in appendFiltersForContentType():
     // If we should save as a complete page, the saveAsType is kSaveAsType_Complete.
     // If we should save as text, the saveAsType is kSaveAsType_Text.
     var useSaveDocument = aDocument &&
                           (((saveMode & SAVEMODE_COMPLETE_DOM) && (saveAsType == kSaveAsType_Complete)) ||
@@ -820,17 +820,17 @@ function DownloadURL(aURL, aFileName, aI
     download.tryToKeepPartialData = true;
 
     // Ignore errors because failures are reported through the download list.
     download.start().catch(() => {});
 
     // Add the download to the list, allowing it to be managed.
     let list = await Downloads.getList(Downloads.ALL);
     list.add(download);
-  })().then(null, Components.utils.reportError);
+  })().catch(Components.utils.reportError);
 }
 
 // We have no DOM, and can only save the URL as is.
 const SAVEMODE_FILEONLY      = 0x00;
 XPCOMUtils.defineConstant(this, "SAVEMODE_FILEONLY", SAVEMODE_FILEONLY);
 // We have a DOM and can save as complete.
 const SAVEMODE_COMPLETE_DOM  = 0x01;
 XPCOMUtils.defineConstant(this, "SAVEMODE_COMPLETE_DOM", SAVEMODE_COMPLETE_DOM);
--- a/toolkit/modules/DeferredTask.jsm
+++ b/toolkit/modules/DeferredTask.jsm
@@ -288,17 +288,17 @@ this.DeferredTask.prototype = {
           this._armed = false;
           await this._runTask();
         }
       }
 
       // Indicate that the execution of the task has finished.  This happens
       // synchronously with the previous state changes in the function.
       this._runningPromise = null;
-    })().then(null, Cu.reportError));
+    })().catch(Cu.reportError));
   },
 
   /**
    * Executes the associated task and catches exceptions.
    */
   async _runTask() {
     try {
       let result = this._taskFn();
--- a/toolkit/modules/ZipUtils.jsm
+++ b/toolkit/modules/ZipUtils.jsm
@@ -142,17 +142,17 @@ this.ZipUtils = {
           } catch (e) {
             dump("extractFilesAsync: failed to extract file " + path + "\n");
             throw e;
           }
         }
       }
 
       zipReader.close();
-    })().then(null, (e) => {
+    })().catch((e) => {
       zipReader.close();
       throw e;
     });
   },
 
   /**
    * Extracts files from a ZIP file into a directory.
    *
--- a/toolkit/mozapps/downloads/nsHelperAppDlg.js
+++ b/toolkit/mozapps/downloads/nsHelperAppDlg.js
@@ -357,17 +357,17 @@ nsUnknownContentTypeDialog.prototype = {
                 return;
               }
 
             }
           }
           aLauncher.saveDestinationAvailable(result);
         });
       });
-    })().then(null, Components.utils.reportError);
+    })().catch(Components.utils.reportError);
   },
 
   getFinalLeafName: function (aLeafName, aFileExt)
   {
     // Remove any leading periods, since we don't want to save hidden files
     // automatically.
     aLeafName = aLeafName.replace(/^\.+/, "");
 
--- a/toolkit/mozapps/extensions/AddonManager.jsm
+++ b/toolkit/mozapps/extensions/AddonManager.jsm
@@ -1515,17 +1515,17 @@ var AddonManagerInternal = {
         }
       }
 
       logger.debug("Background update check complete");
       Services.obs.notifyObservers(null,
                                    "addons-background-update-complete");
     })();
     // Fork the promise chain so we can log the error and let our caller see it too.
-    buPromise.then(null, e => logger.warn("Error in background update", e));
+    buPromise.catch(e => logger.warn("Error in background update", e));
     return buPromise;
   },
 
   /**
    * Adds a add-on to the list of detected changes for this startup. If
    * addStartupChange is called multiple times for the same add-on in the same
    * startup then only the most recent change will be remembered.
    *
--- a/toolkit/mozapps/extensions/DeferredSave.jsm
+++ b/toolkit/mozapps/extensions/DeferredSave.jsm
@@ -197,24 +197,24 @@ this.DeferredSave.prototype = {
 
     // In either the success or the exception handling case, we don't need to handle
     // the error from _writing here; it's already being handled in another then()
     let toSave = null;
     try {
       toSave = this._dataProvider();
     } catch (e) {
         this.logger.error("Deferred save dataProvider failed", e);
-      writing.then(null, error => {})
+      writing.catch(error => {})
         .then(count => {
           pending.reject(e);
         });
       return;
     }
 
-    writing.then(null, error => { return 0; })
+    writing.catch(error => { return 0; })
     .then(count => {
         this.logger.debug("Starting write");
       this.totalSaves++;
       this.writeInProgress = true;
 
       OS.File.writeAtomic(this._path, toSave, {tmpPath: this._path + ".tmp"})
       .then(
         result => {
--- a/toolkit/mozapps/extensions/internal/AddonRepository.jsm
+++ b/toolkit/mozapps/extensions/internal/AddonRepository.jsm
@@ -1652,21 +1652,21 @@ var AddonDatabase = {
    * @param  aCallback
    *         An optional callback to call once complete
    * @return Promise{null} resolves when the database has been deleted
    */
   delete(aCallback) {
     this.DB = BLANK_DB();
 
     this._deleting = this.Writer.flush()
-      .then(null, () => {})
+      .catch(() => {})
       // shutdown(true) never rejects
       .then(() => this.shutdown(true))
       .then(() => OS.File.remove(this.jsonFile, {}))
-      .then(null, error => logger.error("Unable to delete Addon Repository file " +
+      .catch(error => logger.error("Unable to delete Addon Repository file " +
                                  this.jsonFile, error))
       .then(() => this._deleting = null)
       .then(aCallback);
     return this._deleting;
   },
 
   toJSON() {
     let json = {
@@ -1894,18 +1894,17 @@ var AddonDatabase = {
   /**
    * Write the in-memory DB to disk, after waiting for
    * the DB_BATCH_TIMEOUT_MS timeout.
    *
    * @return Promise A promise that resolves after the
    *                 write to disk has completed.
    */
   _saveDBToDisk() {
-    return this.Writer.saveChanges().then(
-      null,
+    return this.Writer.saveChanges().catch(
       e => logger.error("SaveDBToDisk failed", e));
   },
 
   /**
    * Make a developer object from a vanilla
    * JS object from the JSON database
    *
    * @param  aObj
--- a/toolkit/mozapps/extensions/internal/GMPProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/GMPProvider.jsm
@@ -380,17 +380,17 @@ GMPWrapper.prototype = {
     GMPPrefs.reset(GMPPrefs.KEY_UPDATE_LAST_CHECK, null);
     // Delay this in case the user changes his mind and doesn't want to
     // enable EME after all.
     setTimeout(() => {
       if (!this.appDisabled) {
         let gmpInstallManager = new GMPInstallManager();
         // We don't really care about the results, if someone is interested
         // they can check the log.
-        gmpInstallManager.simpleCheckAndInstall().then(null, () => {});
+        gmpInstallManager.simpleCheckAndInstall().catch(() => {});
       }
       this._isUpdateCheckPending = false;
     }, delay);
   },
 
   receiveMessage({target: browser, data: data}) {
     this._log.trace("receiveMessage() data=" + data);
     let parsedData;
--- a/toolkit/mozapps/extensions/internal/XPIInstall.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIInstall.jsm
@@ -1941,17 +1941,17 @@ class AddonInstall {
         }
         XPIProvider.setTelemetry(this.addon.id, "unpacked", installedUnpacked);
         recordAddonTelemetry(this.addon);
 
         // Notify providers that a new theme has been enabled.
         if (isTheme(this.addon.type) && this.addon.active)
           AddonManagerPrivate.notifyAddonChanged(this.addon.id, this.addon.type, requiresRestart);
       }
-    })().then(null, (e) => {
+    })().catch((e) => {
       logger.warn(`Failed to install ${this.file.path} from ${this.sourceURI.spec} to ${stagedAddon.path}`, e);
 
       if (stagedAddon.exists())
         recursiveRemove(stagedAddon);
       this.state = AddonManager.STATE_INSTALL_FAILED;
       this.error = AddonManager.ERROR_FILE_ACCESS;
       XPIProvider.removeActiveInstall(this);
       AddonManagerPrivate.callAddonListeners("onOperationCancelled",
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -6045,17 +6045,17 @@ class MutableDirectoryInstallLocation ex
   requestStagingDir() {
     this._stagingDirLock++;
 
     if (this._stagingDirPromise)
       return this._stagingDirPromise;
 
     OS.File.makeDir(this._directory.path);
     let stagepath = OS.Path.join(this._directory.path, DIR_STAGE);
-    return this._stagingDirPromise = OS.File.makeDir(stagepath).then(null, (e) => {
+    return this._stagingDirPromise = OS.File.makeDir(stagepath).catch((e) => {
       if (e instanceof OS.File.Error && e.becauseExists)
         return;
       logger.error("Failed to create staging directory", e);
       throw e;
     });
   }
 
   releaseStagingDir() {
--- a/toolkit/mozapps/extensions/internal/XPIProviderUtils.js
+++ b/toolkit/mozapps/extensions/internal/XPIProviderUtils.js
@@ -676,17 +676,17 @@ this.XPIDatabase = {
             "XPIDB_saves_overlapped", this._deferredSave.overlappedSaves);
         AddonManagerPrivate.recordSimpleMeasure(
             "XPIDB_saves_late", this._deferredSave.dirty ? 1 : 0);
       }
 
       // Return a promise that any pending writes of the DB are complete and we
       // are finished cleaning up
       let flushPromise = this.flush();
-      flushPromise.then(null, error => {
+      flushPromise.catch(error => {
           logger.error("Flush of XPI database failed", error);
           AddonManagerPrivate.recordSimpleMeasure("XPIDB_shutdownFlush_failed", 1);
           // If our last attempt to read or write the DB failed, force a new
           // extensions.ini to be written to disk on the next startup
           Services.prefs.setBoolPref(PREF_PENDING_OPERATIONS, true);
         })
         .then(count => {
           // Clear out the cached addons data loaded from JSON
@@ -739,17 +739,17 @@ this.XPIDatabase = {
    * @param  aCallback
    *         Called back with the addon, or null if no matching addon is found
    */
   getAddon(aFilter, aCallback) {
     return this.asyncLoadDB().then(
       addonDB => {
         getRepositoryAddon(_findAddon(addonDB, aFilter), makeSafe(aCallback));
       })
-    .then(null,
+    .catch(
         error => {
           logger.error("getAddon failed", error);
           makeSafe(aCallback)(null);
         });
   },
 
   /**
    * Asynchronously gets an add-on with a particular ID in a particular
--- a/toolkit/mozapps/extensions/test/browser/head.js
+++ b/toolkit/mozapps/extensions/test/browser/head.js
@@ -179,17 +179,17 @@ function log_exceptions(aCallback, ...aA
   } catch (e) {
     info("Exception thrown: " + e);
     throw e;
   }
 }
 
 function log_callback(aPromise, aCallback) {
   aPromise.then(aCallback)
-    .then(null, e => info("Exception thrown: " + e));
+    .catch(e => info("Exception thrown: " + e));
   return aPromise;
 }
 
 function add_test(test) {
   gPendingTests.push(test);
 }
 
 function run_next_test() {