Bug 1120178 - Remove DOMError draft
authorAryeh Gregor <ayg@aryeh.name>
Sun, 06 Aug 2017 20:47:00 +0300
changeset 642013 3d12809da308bed01f71ef03aa0a123158dd0703
parent 619581 52285ea5e54c73d3ed824544cef2ee3f195f05e6
child 724872 365b2a488d47a17e301aae9658a65c0e2b13eab1
push id72611
push userbmo:ayg@aryeh.name
push dateMon, 07 Aug 2017 13:47:22 +0000
bugs1120178, 460725, 1675
milestone57.0a1
Bug 1120178 - Remove DOMError This has always been redundant to DOMException and the specs have gotten rid of it a while ago. Chrome has removed it successfully from everywhere except in StorageQuota, where we don't seem to use it (I think?): https://bugs.chromium.org/p/chromium/issues/detail?id=460725 However, they have not yet removed the constructor. Their metrics show it's called in 0.001675% of pages at the time of this writing: https://www.chromestatus.com/metrics/feature/popularity If we take this patch as-is, there might be risk of breaking sites that call the constructor. We could work around it by having the constructor return a DOMException if we wanted. MozReview-Commit-ID: BQjJV9bRT31
dom/base/DOMError.cpp
dom/base/DOMError.h
dom/base/DOMRequest.cpp
dom/base/DOMRequest.h
dom/base/Element.cpp
dom/base/moz.build
dom/base/nsIDOMDOMRequest.idl
dom/base/test/mochitest.ini
dom/base/test/test_domcursor.html
dom/base/test/test_domrequest.html
dom/base/test/test_error.html
dom/bindings/BindingUtils.cpp
dom/bindings/CallbackObject.h
dom/browser-element/mochitest/browserElement_ExecuteScript.js
dom/file/FileReader.cpp
dom/file/FileReader.h
dom/imptests/html/dom/test_interfaces.html
dom/indexedDB/IDBRequest.cpp
dom/indexedDB/IDBRequest.h
dom/indexedDB/IDBTransaction.cpp
dom/indexedDB/IDBTransaction.h
dom/indexedDB/IndexedDatabaseManager.cpp
dom/indexedDB/test/unit/test_setVersion_throw.js
dom/interfaces/base/domstubs.idl
dom/network/TCPSocket.cpp
dom/network/TCPSocket.h
dom/promise/Promise.cpp
dom/promise/Promise.h
dom/tests/mochitest/general/test_interfaces.js
dom/webidl/DOMError.webidl
dom/webidl/DOMException.webidl
dom/webidl/DOMRequest.webidl
dom/webidl/FileReader.webidl
dom/webidl/IDBRequest.webidl
dom/webidl/IDBTransaction.webidl
dom/webidl/RTCPeerConnection.webidl
dom/webidl/moz.build
dom/workers/ServiceWorkerManager.cpp
dom/workers/test/serviceworkers/test_serviceworker_interfaces.js
dom/workers/test/test_worker_interfaces.js
testing/web-platform/meta/IndexedDB/error-attributes.html.ini
testing/web-platform/meta/dom/historical.html.ini
testing/web-platform/tests/IndexedDB/idbobjectstore_createIndex7-event_order.htm
toolkit/components/extensions/test/mochitest/test_ext_unlimitedStorage_legacy_persistent_indexedDB.html
toolkit/components/thumbnails/PageThumbs.jsm
deleted file mode 100644
--- a/dom/base/DOMError.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/dom/DOMError.h"
-#include "mozilla/dom/DOMErrorBinding.h"
-#include "mozilla/dom/DOMException.h"
-#include "nsPIDOMWindow.h"
-
-namespace mozilla {
-namespace dom {
-
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMError, mWindow)
-NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMError)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMError)
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMError)
-  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_INTERFACE_MAP_ENTRY(DOMError)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-DOMError::DOMError(nsPIDOMWindowInner* aWindow)
-  : mWindow(aWindow)
-{
-}
-
-DOMError::DOMError(nsPIDOMWindowInner* aWindow, nsresult aValue)
-  : mWindow(aWindow)
-{
-  nsCString name, message;
-  NS_GetNameAndMessageForDOMNSResult(aValue, name, message);
-
-  CopyUTF8toUTF16(name, mName);
-  CopyUTF8toUTF16(message, mMessage);
-}
-
-DOMError::DOMError(nsPIDOMWindowInner* aWindow, const nsAString& aName)
-  : mWindow(aWindow)
-  , mName(aName)
-{
-}
-
-DOMError::DOMError(nsPIDOMWindowInner* aWindow, const nsAString& aName,
-                   const nsAString& aMessage)
-  : mWindow(aWindow)
-  , mName(aName)
-  , mMessage(aMessage)
-{
-}
-
-DOMError::~DOMError()
-{
-}
-
-JSObject*
-DOMError::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
-  return DOMErrorBinding::Wrap(aCx, this, aGivenProto);
-}
-
-/* static */ already_AddRefed<DOMError>
-DOMError::Constructor(const GlobalObject& aGlobal,
-                      const nsAString& aName, const nsAString& aMessage,
-                      ErrorResult& aRv)
-{
-  nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal.GetAsSupports());
-
-  // Window is null for chrome code.
-
-  RefPtr<DOMError> ret = new DOMError(window, aName, aMessage);
-  return ret.forget();
-}
-
-} // namespace dom
-} // namespace mozilla
deleted file mode 100644
--- a/dom/base/DOMError.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_domerror_h__
-#define mozilla_dom_domerror_h__
-
-#include "mozilla/Attributes.h"
-#include "nsWrapperCache.h"
-#include "nsCOMPtr.h"
-#include "nsString.h"
-
-#define DOMERROR_IID \
-{ 0x220cb63f, 0xa37d, 0x4ba4, \
- { 0x8e, 0x31, 0xfc, 0xde, 0xec, 0x48, 0xe1, 0x66 } }
-
-class nsPIDOMWindowInner;
-
-namespace mozilla {
-
-class ErrorResult;
-
-namespace dom {
-
-class GlobalObject;
-
-class DOMError : public nsISupports,
-                 public nsWrapperCache
-{
-  nsCOMPtr<nsPIDOMWindowInner> mWindow;
-  nsString mName;
-  nsString mMessage;
-
-protected:
-  virtual ~DOMError();
-
-public:
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMError)
-
-  NS_DECLARE_STATIC_IID_ACCESSOR(DOMERROR_IID)
-
-  // aWindow can be null if this DOMError is not associated with a particular
-  // window.
-
-  explicit DOMError(nsPIDOMWindowInner* aWindow);
-
-  DOMError(nsPIDOMWindowInner* aWindow, nsresult aValue);
-
-  DOMError(nsPIDOMWindowInner* aWindow, const nsAString& aName);
-
-  DOMError(nsPIDOMWindowInner* aWindow, const nsAString& aName,
-           const nsAString& aMessage);
-
-  nsPIDOMWindowInner* GetParentObject() const
-  {
-    return mWindow;
-  }
-
-  virtual JSObject*
-  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
-  static already_AddRefed<DOMError>
-  Constructor(const GlobalObject& global, const nsAString& name,
-              const nsAString& message, ErrorResult& aRv);
-
-  void GetName(nsString& aRetval) const
-  {
-    aRetval = mName;
-  }
-
-  void GetMessage(nsString& aRetval) const
-  {
-    aRetval = mMessage;
-  }
-};
-
-NS_DEFINE_STATIC_IID_ACCESSOR(DOMError, DOMERROR_IID)
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_domerror_h__
--- a/dom/base/DOMRequest.cpp
+++ b/dom/base/DOMRequest.cpp
@@ -1,28 +1,28 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "DOMRequest.h"
 
-#include "DOMError.h"
+#include "DOMException.h"
 #include "nsThreadUtils.h"
 #include "DOMCursor.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "jsfriendapi.h"
 #include "nsContentUtils.h"
 
 using mozilla::dom::AnyCallback;
-using mozilla::dom::DOMError;
+using mozilla::dom::DOMException;
 using mozilla::dom::DOMRequest;
 using mozilla::dom::DOMRequestService;
 using mozilla::dom::DOMCursor;
 using mozilla::dom::Promise;
 using mozilla::dom::AutoJSAPI;
 using mozilla::dom::RootingCx;
 
 DOMRequest::DOMRequest(nsPIDOMWindowInner* aWindow)
@@ -106,17 +106,17 @@ DOMRequest::GetResult(JS::MutableHandle<
 {
   GetResult(nullptr, aResult);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 DOMRequest::GetError(nsISupports** aError)
 {
-  NS_IF_ADDREF(*aError = GetError());
+  NS_IF_ADDREF(*aError = static_cast<Exception*>(GetError()));
   return NS_OK;
 }
 
 void
 DOMRequest::FireSuccess(JS::Handle<JS::Value> aResult)
 {
   NS_ASSERTION(!mDone, "mDone shouldn't have been set to true already!");
   NS_ASSERTION(!mError, "mError shouldn't have been set!");
@@ -138,44 +138,46 @@ DOMRequest::FireSuccess(JS::Handle<JS::V
 void
 DOMRequest::FireError(const nsAString& aError)
 {
   NS_ASSERTION(!mDone, "mDone shouldn't have been set to true already!");
   NS_ASSERTION(!mError, "mError shouldn't have been set!");
   NS_ASSERTION(mResult.isUndefined(), "mResult shouldn't have been set!");
 
   mDone = true;
-  mError = new DOMError(GetOwner(), aError);
+  // XXX Error code chosen arbitrarily
+  mError = DOMException::Create(NS_ERROR_DOM_UNKNOWN_ERR,
+                                NS_ConvertUTF16toUTF8(aError));
 
   FireEvent(NS_LITERAL_STRING("error"), true, true);
 
   if (mPromise) {
     mPromise->MaybeRejectBrokenly(mError);
   }
 }
 
 void
 DOMRequest::FireError(nsresult aError)
 {
   NS_ASSERTION(!mDone, "mDone shouldn't have been set to true already!");
   NS_ASSERTION(!mError, "mError shouldn't have been set!");
   NS_ASSERTION(mResult.isUndefined(), "mResult shouldn't have been set!");
 
   mDone = true;
-  mError = new DOMError(GetOwner(), aError);
+  mError = DOMException::Create(aError);
 
   FireEvent(NS_LITERAL_STRING("error"), true, true);
 
   if (mPromise) {
     mPromise->MaybeRejectBrokenly(mError);
   }
 }
 
 void
-DOMRequest::FireDetailedError(DOMError* aError)
+DOMRequest::FireDetailedError(DOMException* aError)
 {
   NS_ASSERTION(!mDone, "mDone shouldn't have been set to true already!");
   NS_ASSERTION(!mError, "mError shouldn't have been set!");
   NS_ASSERTION(mResult.isUndefined(), "mResult shouldn't have been set!");
   NS_ASSERTION(aError, "No detailed error provided");
 
   mDone = true;
   mError = aError;
@@ -284,19 +286,19 @@ DOMRequestService::FireError(nsIDOMDOMRe
   return NS_OK;
 }
 
 NS_IMETHODIMP
 DOMRequestService::FireDetailedError(nsIDOMDOMRequest* aRequest,
                                      nsISupports* aError)
 {
   NS_ENSURE_STATE(aRequest);
-  nsCOMPtr<DOMError> err = do_QueryInterface(aError);
+  nsCOMPtr<nsIException> err = do_QueryInterface(aError);
   NS_ENSURE_STATE(err);
-  static_cast<DOMRequest*>(aRequest)->FireDetailedError(err);
+  static_cast<DOMRequest*>(aRequest)->FireDetailedError(static_cast<DOMException*>(err.get()));
 
   return NS_OK;
 }
 
 class FireSuccessAsyncTask : public mozilla::Runnable
 {
 
   FireSuccessAsyncTask(DOMRequest* aRequest, const JS::Value& aResult)
--- a/dom/base/DOMRequest.h
+++ b/dom/base/DOMRequest.h
@@ -5,17 +5,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_domrequest_h__
 #define mozilla_dom_domrequest_h__
 
 #include "nsIDOMDOMRequest.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/DOMEventTargetHelper.h"
-#include "mozilla/dom/DOMError.h"
+#include "mozilla/dom/DOMException.h"
 #include "mozilla/dom/DOMRequestBinding.h"
 
 #include "nsCOMPtr.h"
 
 namespace mozilla {
 
 class ErrorResult;
 
@@ -24,17 +24,17 @@ namespace dom {
 class AnyCallback;
 class Promise;
 
 class DOMRequest : public DOMEventTargetHelper,
                    public nsIDOMDOMRequest
 {
 protected:
   JS::Heap<JS::Value> mResult;
-  RefPtr<DOMError> mError;
+  RefPtr<DOMException> mError;
   RefPtr<Promise> mPromise;
   bool mDone;
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMDOMREQUEST
   NS_REALLY_FORWARD_NSIDOMEVENTTARGET(DOMEventTargetHelper)
 
@@ -58,17 +58,17 @@ public:
 
   void GetResult(JSContext*, JS::MutableHandle<JS::Value> aRetval) const
   {
     NS_ASSERTION(mDone || mResult.isUndefined(),
                  "Result should be undefined when pending");
     aRetval.set(mResult);
   }
 
-  DOMError* GetError() const
+  DOMException* GetError() const
   {
     NS_ASSERTION(mDone || !mError,
                  "Error should be null when pending");
     return mError;
   }
 
   IMPL_EVENT_HANDLER(success)
   IMPL_EVENT_HANDLER(error)
@@ -77,17 +77,17 @@ public:
   Then(JSContext* aCx, AnyCallback* aResolveCallback,
        AnyCallback* aRejectCallback,
        JS::MutableHandle<JS::Value> aRetval,
        mozilla::ErrorResult& aRv);
 
   void FireSuccess(JS::Handle<JS::Value> aResult);
   void FireError(const nsAString& aError);
   void FireError(nsresult aError);
-  void FireDetailedError(DOMError* aError);
+  void FireDetailedError(DOMException* aError);
 
   explicit DOMRequest(nsPIDOMWindowInner* aWindow);
   explicit DOMRequest(nsIGlobalObject* aGlobal);
 
 protected:
   virtual ~DOMRequest();
 
   void FireEvent(const nsAString& aType, bool aBubble, bool aCancelable);
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -149,16 +149,17 @@
 #include "mozilla/dom/VRDisplay.h"
 #include "mozilla/IntegerPrintfMacros.h"
 #include "mozilla/Preferences.h"
 #include "nsComputedDOMStyle.h"
 #include "nsDOMStringMap.h"
 #include "DOMIntersectionObserver.h"
 
 #include "nsISpeculativeConnect.h"
+#include "nsIIOService.h"
 
 #include "DOMMatrix.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 //
 // Verify sizes of elements on 64-bit platforms. This should catch most memory
--- a/dom/base/moz.build
+++ b/dom/base/moz.build
@@ -158,17 +158,16 @@ EXPORTS.mozilla.dom += [
     'Comment.h',
     'CustomElementRegistry.h',
     'DirectionalityUtils.h',
     'DispatcherTrait.h',
     'DocGroup.h',
     'DocumentFragment.h',
     'DocumentType.h',
     'DOMCursor.h',
-    'DOMError.h',
     'DOMException.h',
     'DOMImplementation.h',
     'DOMIntersectionObserver.h',
     'DOMMatrix.h',
     'DOMParser.h',
     'DOMPoint.h',
     'DOMQuad.h',
     'DOMRect.h',
@@ -235,17 +234,16 @@ UNIFIED_SOURCES += [
     'Crypto.cpp',
     'CustomElementRegistry.cpp',
     'DirectionalityUtils.cpp',
     'DispatcherTrait.cpp',
     'DocGroup.cpp',
     'DocumentFragment.cpp',
     'DocumentType.cpp',
     'DOMCursor.cpp',
-    'DOMError.cpp',
     'DOMException.cpp',
     'DOMImplementation.cpp',
     'DOMMatrix.cpp',
     'DOMParser.cpp',
     'DOMPoint.cpp',
     'DOMQuad.cpp',
     'DOMRect.cpp',
     'DOMRequest.cpp',
--- a/dom/base/nsIDOMDOMRequest.idl
+++ b/dom/base/nsIDOMDOMRequest.idl
@@ -12,17 +12,17 @@ interface nsICursorContinueCallback;
 
 [builtinclass, uuid(e39da69e-2232-4e49-9856-b8a4a6210336)]
 interface nsIDOMDOMRequest : nsIDOMEventTarget
 {
   readonly attribute DOMString readyState; // "pending" or "done"
 
   readonly attribute jsval result;
 
-  // DOMError
+  // DOMException
   readonly attribute nsISupports error;
 
   [implicit_jscontext] attribute jsval onsuccess;
   [implicit_jscontext] attribute jsval onerror;
 };
 
 [scriptable, builtinclass, uuid(9a57e5de-ce93-45fa-8145-755722834f7c)]
 interface nsIDOMRequestService : nsISupports
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -656,17 +656,16 @@ skip-if = toolkit == 'android' || e10s #
 [test_domrequest.html]
 [test_domwindowutils.html]
 [test_e4x_for_each.html]
 [test_element.matches.html]
 [test_element_closest.html]
 [test_elementTraversal.html]
 [test_encodeToStringWithMaxLength.html]
 [test_encodeToStringWithRequiresReinitAfterOutput.html]
-[test_error.html]
 [test_EventSource_redirects.html]
 [test_explicit_user_agent.html]
 skip-if = (toolkit == 'android') # Android: Bug 775227
 [test_getAttribute_after_createAttribute.html]
 [test_getElementById.html]
 [test_getTranslationNodes.html]
 [test_getTranslationNodes_limit.html]
 [test_gsp-qualified.html]
--- a/dom/base/test/test_domcursor.html
+++ b/dom/base/test/test_domcursor.html
@@ -112,17 +112,18 @@ var tests = [
   function() {
     // fire error
     req = reqserv.createCursor(window, function(){});
     req.onerror = function(e) {
       ok(e, "got success event");
       is(e.type, "error", "correct type during error");
       is(e.target, req, "correct target during error");
       is(req.readyState, "done", "correct readyState after error");
-      is(req.error.name, "error msg", "correct error after error");
+      is(req.error.name, "UnknownError", "correct error name after error");
+      is(req.error.message, "error msg", "correct error message after error");
       is(req.result, undefined, "correct result after error");
       try {
         req.continue();
         ok(false, "continue while in an error state should fail");
       } catch (e) {
         ok(true, "continue while in an error state should fail");
       }
 
--- a/dom/base/test/test_domrequest.html
+++ b/dom/base/test/test_domrequest.html
@@ -69,56 +69,58 @@ function testError() {
   req.onerror = function(e) {
     ev = e;
   }
   var error = null;
   var promise = req.then(function(r) {
     ok(false, "promise should not be resolved");
     runTest();
   }, function(e) {
-    ok(e instanceof DOMError, "got error rejection");
+    ok(e instanceof DOMException, "got error rejection");
     ok(e === req.error, "got correct error when rejecting the promise");
     error = e;
     runTest();
   });
   ok(promise instanceof Promise, "then() should return a Promise");
   reqserv.fireError(req, "OhMyError");
   ok(ev, "got error event");
   is(ev.type, "error", "correct type during error");
   is(ev.target, req, "correct target during error");
   is(req.readyState, "done", "correct readyState after error");
-  is(req.error.name, "OhMyError", "correct error after error");
+  is(req.error.name, "UnknownError", "correct error type after error");
+  is(req.error.message, "OhMyError", "correct error message after error");
   is(req.result, undefined, "correct result after error");
   is(error, null, "Promise should not be rejected synchronously");
 }
 
 function testDetailedError() {
   // fire detailed error
   var req = reqserv.createRequest(window);
   var ev = null;
   req.onerror = function(e) {
     ev = e;
   };
   var error = null;
   var promise = req.then(function(r) {
     ok(false, "promise should not be resolved");
     runTest();
   }, function(e) {
-    ok(e instanceof DOMError, "got error rejection");
+    ok(e instanceof DOMException, "got error rejection");
     ok(e === req.error, "got correct error when rejecting the promise");
     error = e;
     runTest();
   });
   ok(promise instanceof Promise, "then() should return a Promise");
-  reqserv.fireDetailedError(req, new DOMError("detailedError"));
+  reqserv.fireDetailedError(req, new DOMException("detailedError"));
   ok(ev, "got error event");
   is(ev.type, "error", "correct type during error");
   is(ev.target, req, "correct target during error");
   is(req.readyState, "done", "correct readyState after error");
-  is(req.error.name, "detailedError", "correct error after error");
+  is(req.error.name, "UnknownError", "correct error type after error");
+  is(req.error.message, "detailedError", "correct error message after error");
   is(req.result, undefined, "correct result after error");
   is(error, null, "Promise should not be rejected synchronously");
 }
 
 function testThenAfterSuccess() {
   // fire success
   var req = reqserv.createRequest(window);
   var ev = null;
@@ -152,24 +154,25 @@ function testThenAfterError() {
   req.onerror = function(e) {
     ev = e;
   }
   reqserv.fireError(req, "OhMyError");
   ok(ev, "got error event");
   is(ev.type, "error", "correct type during error");
   is(ev.target, req, "correct target during error");
   is(req.readyState, "done", "correct readyState after error");
-  is(req.error.name, "OhMyError", "correct error after error");
+  is(req.error.name, "UnknownError", "correct error type after error");
+  is(req.error.message, "OhMyError", "correct error message after error");
   is(req.result, undefined, "correct result after error");
   var error = null;
   var promise = req.then(function(r) {
     ok(false, "promise should not be resolved");
     runTest();
   }, function(e) {
-    ok(e instanceof DOMError, "got error rejection");
+    ok(e instanceof DOMException, "got error rejection");
     ok(e === req.error, "got correct error when rejecting the promise");
     error = e;
     runTest();
   });
   ok(promise instanceof Promise, "then() should return a Promise");
   is(error, null, "Promise should not be rejected synchronously");
 }
 
@@ -180,28 +183,29 @@ function testDetailedError() {
   req.onerror = function(e) {
     ev = e;
   };
   var error = null;
   var promise = req.then(function(r) {
     ok(false, "promise should not be resolved");
     runTest();
   }, function(e) {
-    ok(e instanceof DOMError, "got error rejection");
+    ok(e instanceof DOMException, "got error rejection");
     ok(e === req.error, "got correct error when rejecting the promise");
     error = e;
     runTest();
   });
   ok(promise instanceof Promise, "then() should return a Promise");
-  reqserv.fireDetailedError(req, new DOMError("detailedError"));
+  reqserv.fireDetailedError(req, new DOMException("detailedError"));
   ok(ev, "got error event");
   is(ev.type, "error", "correct type during error");
   is(ev.target, req, "correct target during error");
   is(req.readyState, "done", "correct readyState after error");
-  is(req.error.name, "detailedError", "correct error after error");
+  is(req.error.name, "Error", "correct error type after error");
+  is(req.error.message, "detailedError", "correct error message after error");
   is(req.result, undefined, "correct result after error");
   is(error, null, "Promise should not be rejected synchronously");
 }
 
 var tests = [
   testBasics,
   testSuccess,
   testError,
deleted file mode 100644
--- a/dom/base/test/test_error.html
+++ /dev/null
@@ -1,44 +0,0 @@
-
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=869013
--->
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 869013</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=869013">Mozilla Bug 869013</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-  <iframe name="x" id="x"></iframe>
-  <iframe name="y" id="y"></iframe>
-</div>
-<pre id="test">
-</pre>
-  <script type="application/javascript">
-
-  /** Test for Bug 869013 **/
-  var a = new DOMError('name');
-  ok(a, "DOMError created with name: " + a.name + " and message: " + a.message);
-  is(a.name, "name", "Name is correct");
-  is(a.message, "", "Message is correct");
-
-  a = new DOMError('name1', 'message1');
-  ok(a, "DOMError created with name: " + a.name + " and message: " + a.message);
-  is(a.name, "name1", "Name is correct");
-  is(a.message, "message1", "Message is correct");
-
-  try {
-    a = new DOMError();
-    ok(false, "DOMError should throw if there are not params");
-  } catch(e) {
-    ok(true, "DOMError should throw if there are not params");
-  }
-
-  </script>
-</body>
-</html>
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -34,18 +34,16 @@
 #include "xpcprivate.h"
 #include "XrayWrapper.h"
 #include "nsPrintfCString.h"
 #include "mozilla/Sprintf.h"
 #include "nsGlobalWindow.h"
 
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/CustomElementRegistry.h"
-#include "mozilla/dom/DOMError.h"
-#include "mozilla/dom/DOMErrorBinding.h"
 #include "mozilla/dom/DOMException.h"
 #include "mozilla/dom/ElementBinding.h"
 #include "mozilla/dom/HTMLObjectElement.h"
 #include "mozilla/dom/HTMLObjectElementBinding.h"
 #include "mozilla/dom/HTMLEmbedElement.h"
 #include "mozilla/dom/HTMLElementBinding.h"
 #include "mozilla/dom/HTMLEmbedElementBinding.h"
 #include "mozilla/dom/Promise.h"
--- a/dom/bindings/CallbackObject.h
+++ b/dom/bindings/CallbackObject.h
@@ -134,23 +134,23 @@ public:
   {
     return mIncumbentGlobal;
   }
 
   enum ExceptionHandling {
     // Report any exception and don't throw it to the caller code.
     eReportExceptions,
     // Throw an exception to the caller code if the thrown exception is a
-    // binding object for a DOMError or DOMException from the caller's scope,
-    // otherwise report it.
+    // binding object for a DOMException from the caller's scope, otherwise
+    // report it.
     eRethrowContentExceptions,
     // Throw exceptions to the caller code, unless the caller compartment is
-    // provided, the exception is not a DOMError or DOMException from the
-    // caller compartment, and the caller compartment does not subsume our
-    // unwrapped callback.
+    // provided, the exception is not a DOMException from the caller
+    // compartment, and the caller compartment does not subsume our unwrapped
+    // callback.
     eRethrowExceptions
   };
 
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
   {
     return aMallocSizeOf(this);
   }
 
--- a/dom/browser-element/mochitest/browserElement_ExecuteScript.js
+++ b/dom/browser-element/mochitest/browserElement_ExecuteScript.js
@@ -61,58 +61,58 @@ function runTest() {
           });
       `, {url})
     }, bail).then(rv => {
       ok(c(rv, {a:43,b:34}), `scriptId: ${scriptId++}`);
       return iframe.executeScript(`
         … syntax error
       `, {url});
     }, bail).then(bail, (error) => {
-      is(error.name, 'SyntaxError: illegal character', `scriptId: ${scriptId++}`);
+      is(error.message, 'SyntaxError: illegal character', `scriptId: ${scriptId++}`);
       return iframe.executeScript(`
         window
       `, {url});
     }).then(bail, (error) => {
-      is(error.name, 'Script last expression must be a promise or a JSON object', `scriptId: ${scriptId++}`);
+      is(error.message, 'Script last expression must be a promise or a JSON object', `scriptId: ${scriptId++}`);
       return iframe.executeScript(`
           new Promise((resolve, reject) => {
             reject('BOOM');
           });
       `, {url});
     }).then(bail, (error) => {
-      is(error.name, 'BOOM', `scriptId: ${scriptId++}`);
+      is(error.message, 'BOOM', `scriptId: ${scriptId++}`);
       return iframe.executeScript(`
           new Promise((resolve, reject) => {
             resolve(window);
           });
       `, {url});
     }).then(bail, (error) => {
-      is(error.name, 'Value returned (resolve) by promise is not a valid JSON object', `scriptId: ${scriptId++}`);
+      is(error.message, 'Value returned (resolve) by promise is not a valid JSON object', `scriptId: ${scriptId++}`);
       return iframe.executeScript('window.btoa("a")', {url})
     }, bail).then(rv => {
       ok(c(rv, 'YQ=='), `scriptId: ${scriptId++}`);
       return iframe.executeScript('window.wrappedJSObject.btoa("a")', {url})
     }, bail).then(bail, (error) => {
-      is(error.name, 'TypeError: window.wrappedJSObject is undefined', `scriptId: ${scriptId++}`);
+      is(error.message, 'TypeError: window.wrappedJSObject is undefined', `scriptId: ${scriptId++}`);
       return iframe.executeScript('42', {})
     }).then(bail, error => {
       is(error.name, 'InvalidAccessError', `scriptId: ${scriptId++}`);
       return iframe.executeScript('42');
     }).then(bail, error => {
       is(error.name, 'InvalidAccessError', `scriptId: ${scriptId++}`);
       return iframe.executeScript('43', { url: 'http://foo.com' });
     }).then(bail, (error) => {
-      is(error.name, 'URL mismatches', `scriptId: ${scriptId++}`);
+      is(error.message, 'URL mismatches', `scriptId: ${scriptId++}`);
       return iframe.executeScript('43', { url: '_' });
     }, bail).then(bail, (error) => {
-      is(error.name, 'Malformed URL', `scriptId: ${scriptId++}`);
+      is(error.message, 'Malformed URL', `scriptId: ${scriptId++}`);
       return iframe.executeScript('43', { origin: 'http://foo.com' });
     }, bail).then(bail, (error) => {
-      is(error.name, 'Origin mismatches', `scriptId: ${scriptId++}`);
+      is(error.message, 'Origin mismatches', `scriptId: ${scriptId++}`);
       return iframe.executeScript('43', { origin: 'https://example.org' });
     }, bail).then(bail, (error) => {
-      is(error.name, 'Origin mismatches', `scriptId: ${scriptId++}`);
+      is(error.message, 'Origin mismatches', `scriptId: ${scriptId++}`);
       SimpleTest.finish();
     });
   }
 }
 
 addEventListener('testready', runTest);
--- a/dom/file/FileReader.cpp
+++ b/dom/file/FileReader.cpp
@@ -9,17 +9,17 @@
 #include "nsIEventTarget.h"
 #include "nsIGlobalObject.h"
 #include "nsITimer.h"
 #include "nsITransport.h"
 #include "nsIStreamTransportService.h"
 
 #include "mozilla/Base64.h"
 #include "mozilla/CheckedInt.h"
-#include "mozilla/dom/DOMError.h"
+#include "mozilla/dom/DOMException.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/FileReaderBinding.h"
 #include "mozilla/dom/ProgressEvent.h"
 #include "mozilla/Encoding.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsDOMJSUtils.h"
 #include "nsError.h"
 #include "nsNetCID.h"
@@ -249,19 +249,22 @@ FileReader::OnLoadEndArrayBuffer()
   }
 
   nsAutoString errorName;
   JSFlatString* name = js::GetErrorTypeName(cx, er->exnType);
   if (name) {
     AssignJSFlatString(errorName, name);
   }
 
+  nsAutoCString errorMsg(er->message().c_str());
+  nsAutoCString errorNameC = NS_LossyConvertUTF16toASCII(errorName);
+  // XXX Code selected arbitrarily
   mError =
-    new DOMError(GetOwner(), errorName,
-                 NS_ConvertUTF8toUTF16(er->message().c_str()));
+    new DOMException(NS_ERROR_DOM_INVALID_STATE_ERR, errorMsg,
+                     errorNameC, DOMException::INVALID_STATE_ERR);
 
   FreeDataAndDispatchError();
 }
 
 nsresult
 FileReader::DoAsyncWait()
 {
   nsresult rv = IncreaseBusyCounter();
@@ -582,23 +585,23 @@ FileReader::FreeDataAndDispatchError()
 }
 
 void
 FileReader::FreeDataAndDispatchError(nsresult aRv)
 {
   // Set the status attribute, and dispatch the error event
   switch (aRv) {
   case NS_ERROR_FILE_NOT_FOUND:
-    mError = new DOMError(GetOwner(), NS_LITERAL_STRING("NotFoundError"));
+    mError = DOMException::Create(NS_ERROR_DOM_NOT_FOUND_ERR);
     break;
   case NS_ERROR_FILE_ACCESS_DENIED:
-    mError = new DOMError(GetOwner(), NS_LITERAL_STRING("SecurityError"));
+    mError = DOMException::Create(NS_ERROR_DOM_SECURITY_ERR);
     break;
   default:
-    mError = new DOMError(GetOwner(), NS_LITERAL_STRING("NotReadableError"));
+    mError = DOMException::Create(NS_ERROR_DOM_FILE_NOT_READABLE_ERR);
     break;
   }
 
   FreeDataAndDispatchError();
 }
 
 nsresult
 FileReader::DispatchProgressEvent(const nsAString& aType)
@@ -755,17 +758,17 @@ FileReader::Abort()
 
   MOZ_ASSERT(mReadyState == LOADING);
 
   ClearProgressEventTimer();
 
   mReadyState = DONE;
 
   // XXX The spec doesn't say this
-  mError = new DOMError(GetOwner(), NS_LITERAL_STRING("AbortError"));
+  mError = DOMException::Create(NS_ERROR_DOM_ABORT_ERR);
 
   // Revert status and result attributes
   SetDOMStringToNull(mResult);
   mResultArrayBuffer = nullptr;
 
   mAsyncStream = nullptr;
   mBufferedStream = nullptr;
   mBlob = nullptr;
--- a/dom/file/FileReader.h
+++ b/dom/file/FileReader.h
@@ -22,17 +22,17 @@
 
 class nsITimer;
 class nsIEventTarget;
 
 namespace mozilla {
 namespace dom {
 
 class Blob;
-class DOMError;
+class DOMException;
 
 namespace workers {
 class WorkerPrivate;
 }
 
 extern const uint64_t kUnknownSize;
 
 class FileReaderDecreaseBusyCounter;
@@ -84,17 +84,17 @@ public:
 
   void Abort();
 
   uint16_t ReadyState() const
   {
     return static_cast<uint16_t>(mReadyState);
   }
 
-  DOMError* GetError() const
+  DOMException* GetError() const
   {
     return mError;
   }
 
   void GetResult(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
                  ErrorResult& aRv);
 
   IMPL_EVENT_HANDLER(loadstart)
@@ -180,17 +180,17 @@ private:
 
   nsCOMPtr<nsITimer> mProgressNotifier;
   bool mProgressEventWasDelayed;
   bool mTimerIsActive;
 
   nsCOMPtr<nsIAsyncInputStream> mAsyncStream;
   nsCOMPtr<nsIInputStream> mBufferedStream;
 
-  RefPtr<DOMError> mError;
+  RefPtr<DOMException> mError;
 
   eReadyState mReadyState;
 
   uint64_t mTotal;
   uint64_t mTransferred;
 
   nsCOMPtr<nsIEventTarget> mTarget;
 
--- a/dom/imptests/html/dom/test_interfaces.html
+++ b/dom/imptests/html/dom/test_interfaces.html
@@ -5,21 +5,16 @@
 <script src=/resources/testharnessreport.js></script>
 <script src=/resources/WebIDLParser.js></script>
 <script src=/resources/idlharness.js></script>
 
 <h1>DOM IDL tests</h1>
 <div id=log></div>
 
 <script type=text/plain>
-[Constructor(DOMString name)]
-interface DOMError {
-  readonly attribute DOMString name;
-};
-
 [Constructor(DOMString type, optional EventInit eventInitDict)]
 interface Event {
   readonly attribute DOMString type;
   readonly attribute EventTarget? target;
   readonly attribute EventTarget? currentTarget;
 
   const unsigned short NONE = 0;
   const unsigned short CAPTURING_PHASE = 1;
--- a/dom/indexedDB/IDBRequest.cpp
+++ b/dom/indexedDB/IDBRequest.cpp
@@ -14,17 +14,17 @@
 #include "IDBIndex.h"
 #include "IDBObjectStore.h"
 #include "IDBTransaction.h"
 #include "IndexedDatabaseManager.h"
 #include "mozilla/ContentEvents.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/Move.h"
-#include "mozilla/dom/DOMError.h"
+#include "mozilla/dom/DOMException.h"
 #include "mozilla/dom/ErrorEventBinding.h"
 #include "mozilla/dom/IDBOpenDBRequestBinding.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h"
 #include "nsIScriptContext.h"
 #include "nsJSUtils.h"
 #include "nsPIDOMWindow.h"
@@ -214,34 +214,34 @@ void
 IDBRequest::SetError(nsresult aRv)
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(NS_FAILED(aRv));
   MOZ_ASSERT(NS_ERROR_GET_MODULE(aRv) == NS_ERROR_MODULE_DOM_INDEXEDDB);
   MOZ_ASSERT(!mError);
 
   mHaveResultOrErrorCode = true;
-  mError = new DOMError(GetOwner(), aRv);
+  mError = DOMException::Create(aRv);
   mErrorCode = aRv;
 
   mResultVal.setUndefined();
 }
 
 #ifdef DEBUG
 
 nsresult
 IDBRequest::GetErrorCode() const
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(mHaveResultOrErrorCode);
 
   return mErrorCode;
 }
 
-DOMError*
+DOMException*
 IDBRequest::GetErrorAfterResult() const
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(mHaveResultOrErrorCode);
 
   return mError;
 }
 
@@ -353,17 +353,17 @@ IDBRequest::SetResultCallback(ResultCall
   }
 
   mError = nullptr;
   mResultVal = result;
 
   mHaveResultOrErrorCode = true;
 }
 
-DOMError*
+DOMException*
 IDBRequest::GetError(ErrorResult& aRv)
 {
   AssertIsOnOwningThread();
 
   if (!mHaveResultOrErrorCode) {
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return nullptr;
   }
--- a/dom/indexedDB/IDBRequest.h
+++ b/dom/indexedDB/IDBRequest.h
@@ -21,17 +21,17 @@
 class nsPIDOMWindowInner;
 
 namespace mozilla {
 
 class ErrorResult;
 
 namespace dom {
 
-class DOMError;
+class DOMException;
 class IDBCursor;
 class IDBDatabase;
 class IDBFactory;
 class IDBIndex;
 class IDBObjectStore;
 class IDBTransaction;
 template <typename> struct Nullable;
 class OwningIDBObjectStoreOrIDBIndexOrIDBCursor;
@@ -44,17 +44,17 @@ protected:
   // be set. mSourceAsCursor is sometimes set also.
   RefPtr<IDBObjectStore> mSourceAsObjectStore;
   RefPtr<IDBIndex> mSourceAsIndex;
   RefPtr<IDBCursor> mSourceAsCursor;
 
   RefPtr<IDBTransaction> mTransaction;
 
   JS::Heap<JS::Value> mResultVal;
-  RefPtr<DOMError> mError;
+  RefPtr<DOMException> mError;
 
   nsString mFilename;
   uint64_t mLoggingSerialNumber;
   nsresult mErrorCode;
   uint32_t mLineNo;
   uint32_t mColumn;
   bool mHaveResultOrErrorCode;
 
@@ -104,27 +104,27 @@ public:
 #ifdef DEBUG
   ;
 #else
   {
     return mErrorCode;
   }
 #endif
 
-  DOMError*
+  DOMException*
   GetErrorAfterResult() const
 #ifdef DEBUG
   ;
 #else
   {
     return mError;
   }
 #endif
 
-  DOMError*
+  DOMException*
   GetError(ErrorResult& aRv);
 
   void
   GetCallerLocation(nsAString& aFilename, uint32_t* aLineNo,
                     uint32_t* aColumn) const;
 
   bool
   IsPending() const
--- a/dom/indexedDB/IDBTransaction.cpp
+++ b/dom/indexedDB/IDBTransaction.cpp
@@ -8,17 +8,17 @@
 
 #include "BackgroundChildImpl.h"
 #include "IDBDatabase.h"
 #include "IDBEvents.h"
 #include "IDBObjectStore.h"
 #include "IDBRequest.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/EventDispatcher.h"
-#include "mozilla/dom/DOMError.h"
+#include "mozilla/dom/DOMException.h"
 #include "mozilla/dom/DOMStringList.h"
 #include "mozilla/ipc/BackgroundChild.h"
 #include "nsAutoPtr.h"
 #include "nsPIDOMWindow.h"
 #include "nsQueryObject.h"
 #include "nsServiceManagerUtils.h"
 #include "nsTHashtable.h"
 #include "ProfilerHelpers.h"
@@ -658,23 +658,23 @@ IDBTransaction::RenameIndex(IDBObjectSto
   MOZ_ALWAYS_TRUE(mBackgroundActor.mVersionChangeBackgroundActor->
                     SendRenameIndex(aObjectStore->Id(),
                                     aIndexId,
                                     nsString(aName)));
 }
 
 void
 IDBTransaction::AbortInternal(nsresult aAbortCode,
-                              already_AddRefed<DOMError> aError)
+                              already_AddRefed<DOMException> aError)
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(NS_FAILED(aAbortCode));
   MOZ_ASSERT(!IsCommittingOrDone());
 
-  RefPtr<DOMError> error = aError;
+  RefPtr<DOMException> error = aError;
 
   const bool isVersionChange = mMode == VERSION_CHANGE;
   const bool isInvalidated = mDatabase->IsInvalidated();
   bool needToSendAbort = mReadyState == INITIAL;
 
   mAbortCode = aAbortCode;
   mReadyState = DONE;
   mError = error.forget();
@@ -762,33 +762,33 @@ IDBTransaction::Abort(IDBRequest* aReque
 
   if (IsCommittingOrDone()) {
     // Already started (and maybe finished) the commit or abort so there is
     // nothing to do here.
     return;
   }
 
   ErrorResult rv;
-  RefPtr<DOMError> error = aRequest->GetError(rv);
+  RefPtr<DOMException> error = aRequest->GetError(rv);
 
   AbortInternal(aRequest->GetErrorCode(), error.forget());
 }
 
 void
 IDBTransaction::Abort(nsresult aErrorCode)
 {
   AssertIsOnOwningThread();
 
   if (IsCommittingOrDone()) {
     // Already started (and maybe finished) the commit or abort so there is
     // nothing to do here.
     return;
   }
 
-  RefPtr<DOMError> error = new DOMError(GetOwner(), aErrorCode);
+  RefPtr<DOMException> error = DOMException::Create(aErrorCode);
   AbortInternal(aErrorCode, error.forget());
 }
 
 void
 IDBTransaction::Abort(ErrorResult& aRv)
 {
   AssertIsOnOwningThread();
 
@@ -826,17 +826,17 @@ IDBTransaction::FireCompleteOrAbortEvent
                                eNotCancelable);
     MOZ_ASSERT(event);
   } else {
     if (aResult == NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR) {
       mDatabase->SetQuotaExceeded();
     }
 
     if (!mError && !mAbortedByScript) {
-      mError = new DOMError(GetOwner(), aResult);
+      mError = DOMException::Create(aResult);
     }
 
     event = CreateGenericEvent(this,
                                nsDependentString(kAbortEventType),
                                eDoesBubble,
                                eNotCancelable);
     MOZ_ASSERT(event);
   }
@@ -920,17 +920,17 @@ IDBTransaction::GetMode(ErrorResult& aRv
       return IDBTransactionMode::Versionchange;
 
     case MODE_INVALID:
     default:
       MOZ_CRASH("Bad mode!");
   }
 }
 
-DOMError*
+DOMException*
 IDBTransaction::GetError() const
 {
   AssertIsOnOwningThread();
 
   return mError;
 }
 
 already_AddRefed<DOMStringList>
--- a/dom/indexedDB/IDBTransaction.h
+++ b/dom/indexedDB/IDBTransaction.h
@@ -20,17 +20,17 @@ class nsPIDOMWindowInner;
 
 namespace mozilla {
 
 class ErrorResult;
 class EventChainPreVisitor;
 
 namespace dom {
 
-class DOMError;
+class DOMException;
 class DOMStringList;
 class IDBDatabase;
 class IDBObjectStore;
 class IDBOpenDBRequest;
 class IDBRequest;
 
 namespace indexedDB {
 class BackgroundCursorChild;
@@ -71,17 +71,17 @@ public:
     INITIAL = 0,
     LOADING,
     COMMITTING,
     DONE
   };
 
 private:
   RefPtr<IDBDatabase> mDatabase;
-  RefPtr<DOMError> mError;
+  RefPtr<DOMException> mError;
   nsTArray<nsString> mObjectStoreNames;
   nsTArray<RefPtr<IDBObjectStore>> mObjectStores;
   nsTArray<RefPtr<IDBObjectStore>> mDeletedObjectStores;
   nsAutoPtr<WorkerHolder> mWorkerHolder;
 
   // Tagged with mMode. If mMode is VERSION_CHANGE then mBackgroundActor will be
   // a BackgroundVersionChangeTransactionChild. Otherwise it will be a
   // BackgroundTransactionChild.
@@ -277,17 +277,17 @@ public:
   }
 
   nsPIDOMWindowInner*
   GetParentObject() const;
 
   IDBTransactionMode
   GetMode(ErrorResult& aRv) const;
 
-  DOMError*
+  DOMException*
   GetError() const;
 
   already_AddRefed<IDBObjectStore>
   ObjectStore(const nsAString& aName, ErrorResult& aRv);
 
   void
   Abort(ErrorResult& aRv);
 
@@ -323,17 +323,17 @@ public:
 
 private:
   IDBTransaction(IDBDatabase* aDatabase,
                  const nsTArray<nsString>& aObjectStoreNames,
                  Mode aMode);
   ~IDBTransaction();
 
   void
-  AbortInternal(nsresult aAbortCode, already_AddRefed<DOMError> aError);
+  AbortInternal(nsresult aAbortCode, already_AddRefed<DOMException> aError);
 
   void
   SendCommit();
 
   void
   SendAbort(nsresult aResultCode);
 
   void
--- a/dom/indexedDB/IndexedDatabaseManager.cpp
+++ b/dom/indexedDB/IndexedDatabaseManager.cpp
@@ -18,17 +18,17 @@
 
 #include "jsapi.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/CondVar.h"
 #include "mozilla/ContentEvents.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
-#include "mozilla/dom/DOMError.h"
+#include "mozilla/dom/DOMException.h"
 #include "mozilla/dom/ErrorEvent.h"
 #include "mozilla/dom/ErrorEventBinding.h"
 #include "mozilla/dom/quota/QuotaManager.h"
 #include "mozilla/ipc/BackgroundChild.h"
 #include "mozilla/ipc/BackgroundParent.h"
 #include "mozilla/ipc/PBackgroundChild.h"
 #include "nsContentUtils.h"
 #include "nsGlobalWindow.h"
@@ -532,17 +532,17 @@ IndexedDatabaseManager::CommonPostHandle
   // Only mess with events that were originally targeted to an IDBRequest.
   RefPtr<IDBRequest> request;
   if (NS_FAILED(eventTarget->QueryInterface(kIDBRequestIID,
                                             getter_AddRefs(request))) ||
       !request) {
     return NS_OK;
   }
 
-  RefPtr<DOMError> error = request->GetErrorAfterResult();
+  RefPtr<DOMException> error = request->GetErrorAfterResult();
 
   nsString errorName;
   if (error) {
     error->GetName(errorName);
   }
 
   RootedDictionary<ErrorEventInit> init(RootingCx());
   request->GetCallerLocation(init.mFilename, &init.mLineno, &init.mColno);
--- a/dom/indexedDB/test/unit/test_setVersion_throw.js
+++ b/dom/indexedDB/test/unit/test_setVersion_throw.js
@@ -42,13 +42,13 @@ function* testSteps()
     // eslint-disable-next-line no-undef
     trigger_js_exception_by_calling_a_nonexistent_function();
   };
   event = yield undefined;
 
   event.preventDefault();
 
   is(event.type, "error", "Got an error event for db 2");
-  ok(event.target.error instanceof DOMError, "Request has a DOMError");
+  ok(event.target.error instanceof DOMException, "Request has a DOMException");
   is(event.target.error.name, "AbortError", "Request has AbortError");
 
   finishTest();
 }
--- a/dom/interfaces/base/domstubs.idl
+++ b/dom/interfaces/base/domstubs.idl
@@ -27,17 +27,24 @@ interface nsIDOMElement;
 interface nsIDOMNode;
 interface nsIDOMNodeList;
 interface nsIDOMProcessingInstruction;
 interface nsIDOMText;
 interface nsIDOMClientRect;
 interface nsIDOMClientRectList;
 
 // Needed for raises() in our IDL
-interface DOMException;
+// XXX How do I get this declared with the proper namespace?
+%{C++
+namespace mozilla {
+namespace dom {
+class DOMException;
+}
+}
+%}
 
 // Style Sheets
 interface nsIDOMStyleSheetList;
 interface nsIDOMStyleSheet;
 interface nsIDOMMediaList;
 
 // Base
 interface nsIDOMWindow;
--- a/dom/network/TCPSocket.cpp
+++ b/dom/network/TCPSocket.cpp
@@ -2,17 +2,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/ErrorResult.h"
 #include "TCPSocket.h"
 #include "TCPServerSocket.h"
 #include "TCPSocketChild.h"
-#include "mozilla/dom/DOMError.h"
 #include "mozilla/dom/TCPSocketBinding.h"
 #include "mozilla/dom/TCPSocketErrorEvent.h"
 #include "mozilla/dom/TCPSocketErrorEventBinding.h"
 #include "mozilla/dom/TCPSocketEvent.h"
 #include "mozilla/dom/TCPSocketEventBinding.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "nsContentUtils.h"
 #include "nsIArrayBufferInputStream.h"
--- a/dom/network/TCPSocket.h
+++ b/dom/network/TCPSocket.h
@@ -25,17 +25,16 @@ class nsIMultiplexInputStream;
 class nsIAsyncStreamCopier;
 class nsIInputStream;
 class nsINetworkInfo;
 
 namespace mozilla {
 class ErrorResult;
 namespace dom {
 
-class DOMError;
 struct ServerSocketOptions;
 class TCPServerSocket;
 class TCPSocketChild;
 class TCPSocketParent;
 
 // This interface is only used for legacy navigator.mozTCPSocket API compatibility.
 class LegacyMozTCPSocket : public nsISupports
 {
--- a/dom/promise/Promise.cpp
+++ b/dom/promise/Promise.cpp
@@ -9,17 +9,16 @@
 #include "js/Debug.h"
 
 #include "mozilla/Atomics.h"
 #include "mozilla/CycleCollectedJSContext.h"
 #include "mozilla/OwningNonNull.h"
 #include "mozilla/Preferences.h"
 
 #include "mozilla/dom/BindingUtils.h"
-#include "mozilla/dom/DOMError.h"
 #include "mozilla/dom/DOMException.h"
 #include "mozilla/dom/DOMExceptionBinding.h"
 #include "mozilla/dom/MediaStreamError.h"
 #include "mozilla/dom/PromiseBinding.h"
 #include "mozilla/dom/ScriptSettings.h"
 
 #include "jsfriendapi.h"
 #include "js/StructuredClone.h"
@@ -899,17 +898,17 @@ PromiseWorkerProxy::CustomWriteHandler(J
     return false;
   }
 
   return mCallbacks->Write(aCx, aWriter, this, aObj);
 }
 
 // Specializations of MaybeRejectBrokenly we actually support.
 template<>
-void Promise::MaybeRejectBrokenly(const RefPtr<DOMError>& aArg) {
+void Promise::MaybeRejectBrokenly(const RefPtr<DOMException>& aArg) {
   MaybeSomething(aArg, &Promise::MaybeReject);
 }
 template<>
 void Promise::MaybeRejectBrokenly(const nsAString& aArg) {
   MaybeSomething(aArg, &Promise::MaybeReject);
 }
 
 Promise::PromiseState
--- a/dom/promise/Promise.h
+++ b/dom/promise/Promise.h
@@ -22,17 +22,16 @@
 #include "jspubtd.h"
 
 class nsIGlobalObject;
 
 namespace mozilla {
 namespace dom {
 
 class AnyCallback;
-class DOMError;
 class MediaStreamError;
 class PromiseInit;
 class PromiseNativeHandler;
 class PromiseDebugging;
 
 #define NS_PROMISE_IID \
   { 0x1b8d6215, 0x3e67, 0x43ba, \
     { 0x8a, 0xf9, 0x31, 0x5e, 0x8f, 0xce, 0x75, 0x65 } }
@@ -90,21 +89,21 @@ public:
   }
 
   void MaybeReject(const RefPtr<MediaStreamError>& aArg);
 
   void MaybeRejectWithUndefined();
 
   // DO NOT USE MaybeRejectBrokenly with in new code.  Promises should be
   // rejected with Error instances.
-  // Note: MaybeRejectBrokenly is a template so we can use it with DOMError
-  // without instantiating the DOMError specialization of MaybeSomething in
+  // Note: MaybeRejectBrokenly is a template so we can use it with DOMException
+  // without instantiating the DOMException specialization of MaybeSomething in
   // every translation unit that includes this header, because that would
-  // require use to include DOMError.h either here or in all those translation
-  // units.
+  // require use to include DOMException.h either here or in all those
+  // translation units.
   template<typename T>
   void MaybeRejectBrokenly(const T& aArg); // Not implemented by default; see
                                            // specializations in the .cpp for
                                            // the T values we support.
 
   // Called by DOM to let us execute our callbacks.  May be called recursively.
   // Returns true if at least one microtask was processed.
   static bool PerformMicroTaskCheckpoint();
--- a/dom/tests/mochitest/general/test_interfaces.js
+++ b/dom/tests/mochitest/general/test_interfaces.js
@@ -292,18 +292,16 @@ var interfaceNamesInGlobalScope =
     {name: "DocumentTimeline", release: false},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "DocumentType",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "DOMConstructor", xbl: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "DOMCursor",
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    "DOMError",
-// IMPORTANT: Do not change this list without review from a DOM peer!
     "DOMException",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "DOMImplementation",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "DOMMatrix",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "DOMMatrixReadOnly",
 // IMPORTANT: Do not change this list without review from a DOM peer!
deleted file mode 100644
--- a/dom/webidl/DOMError.webidl
+++ /dev/null
@@ -1,21 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * http://dom.spec.whatwg.org/#domerror
- *
- * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
- * liability, trademark and document use rules apply.
- */
-
-[Constructor(DOMString name, optional DOMString message = ""),
- Exposed=(Window,Worker,System)]
-interface DOMError {
-  [Constant]
-  readonly attribute DOMString name;
-
-  [Constant]
-  readonly attribute DOMString message;
-};
--- a/dom/webidl/DOMException.webidl
+++ b/dom/webidl/DOMException.webidl
@@ -11,17 +11,17 @@
  */
 
 
 // This is the WebIDL version of nsIException.  This is mostly legacy stuff.
 
 interface StackFrame;
 
 [NoInterfaceObject,
- Exposed=(Window,Worker)]
+ Exposed=(Window,Worker,System)]
 interface ExceptionMembers
 {
   // A custom message set by the thrower.
   readonly attribute DOMString               message;
   // The nsresult associated with this exception.
   readonly attribute unsigned long           result;
   // The name of the error code (ie, a string repr of |result|).
   readonly attribute DOMString               name;
@@ -61,17 +61,17 @@ interface Exception {
   stringifier;
 };
 
 Exception implements ExceptionMembers;
 
 // XXXkhuey this is an 'exception', not an interface, but we don't have any
 // parser or codegen mechanisms for dealing with exceptions.
 [ExceptionClass,
- Exposed=(Window, Worker),
+ Exposed=(Window, Worker, System),
  Constructor(optional DOMString message = "", optional DOMString name)]
 interface DOMException {
   const unsigned short INDEX_SIZE_ERR = 1;
   const unsigned short DOMSTRING_SIZE_ERR = 2; // historical
   const unsigned short HIERARCHY_REQUEST_ERR = 3;
   const unsigned short WRONG_DOCUMENT_ERR = 4;
   const unsigned short INVALID_CHARACTER_ERR = 5;
   const unsigned short NO_DATA_ALLOWED_ERR = 6; // historical
--- a/dom/webidl/DOMRequest.webidl
+++ b/dom/webidl/DOMRequest.webidl
@@ -5,17 +5,17 @@
 
 enum DOMRequestReadyState { "pending", "done" };
 
 [Exposed=(Window,Worker,System), NoInterfaceObject]
 interface DOMRequestShared {
   readonly attribute DOMRequestReadyState readyState;
 
   readonly attribute any result;
-  readonly attribute DOMError? error;
+  readonly attribute DOMException? error;
 
   attribute EventHandler onsuccess;
   attribute EventHandler onerror;
 };
 
 [Exposed=(Window,Worker,System)]
 interface DOMRequest : EventTarget {
   // The [TreatNonCallableAsNull] annotation is required since then() should do
--- a/dom/webidl/FileReader.webidl
+++ b/dom/webidl/FileReader.webidl
@@ -31,17 +31,17 @@ interface FileReader : EventTarget {
 
   readonly attribute unsigned short readyState;
 
   // File or Blob data
   // bug 858217: readonly attribute (DOMString or ArrayBuffer)? result;
   [Throws]
   readonly attribute any result;
 
-  readonly attribute DOMError? error;
+  readonly attribute DOMException? error;
 
   // event handler attributes
   attribute EventHandler onloadstart;
   attribute EventHandler onprogress;
   attribute EventHandler onload;
   attribute EventHandler onabort;
   attribute EventHandler onerror;
   attribute EventHandler onloadend;
--- a/dom/webidl/IDBRequest.webidl
+++ b/dom/webidl/IDBRequest.webidl
@@ -14,17 +14,17 @@ enum IDBRequestReadyState {
 };
 
 [Exposed=(Window,Worker,System)]
 interface IDBRequest : EventTarget {
     [Throws]
     readonly    attribute any                  result;
 
     [Throws]
-    readonly    attribute DOMError?            error;
+    readonly    attribute DOMException?        error;
 
     readonly    attribute (IDBObjectStore or IDBIndex or IDBCursor)? source;
     readonly    attribute IDBTransaction?      transaction;
     readonly    attribute IDBRequestReadyState readyState;
 
                 attribute EventHandler         onsuccess;
 
                 attribute EventHandler         onerror;
--- a/dom/webidl/IDBTransaction.webidl
+++ b/dom/webidl/IDBTransaction.webidl
@@ -20,17 +20,17 @@ enum IDBTransactionMode {
 };
 
 [Exposed=(Window,Worker,System)]
 interface IDBTransaction : EventTarget {
     [Throws]
     readonly    attribute IDBTransactionMode mode;
     readonly    attribute IDBDatabase        db;
 
-    readonly    attribute DOMError?          error;
+    readonly    attribute DOMException?      error;
 
     [Throws]
     IDBObjectStore objectStore (DOMString name);
 
     [Throws]
     void           abort();
 
                 attribute EventHandler       onabort;
--- a/dom/webidl/RTCPeerConnection.webidl
+++ b/dom/webidl/RTCPeerConnection.webidl
@@ -3,17 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  *
  * The origin of this IDL file is
  * http://w3c.github.io/webrtc-pc/#interface-definition
  */
 
 callback RTCSessionDescriptionCallback = void (RTCSessionDescriptionInit description);
-callback RTCPeerConnectionErrorCallback = void (DOMError error);
+callback RTCPeerConnectionErrorCallback = void (DOMException error);
 callback RTCStatsCallback = void (RTCStatsReport report);
 
 enum RTCSignalingState {
     "stable",
     "have-local-offer",
     "have-remote-offer",
     "have-local-pranswer",
     "have-remote-pranswer",
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -485,17 +485,16 @@ WEBIDL_FILES = [
     'DesktopNotification.webidl',
     'DeviceMotionEvent.webidl',
     'Directory.webidl',
     'Document.webidl',
     'DocumentFragment.webidl',
     'DocumentTimeline.webidl',
     'DocumentType.webidl',
     'DOMCursor.webidl',
-    'DOMError.webidl',
     'DOMException.webidl',
     'DOMImplementation.webidl',
     'DominatorTree.webidl',
     'DOMMatrix.webidl',
     'DOMParser.webidl',
     'DOMPoint.webidl',
     'DOMQuad.webidl',
     'DOMRect.webidl',
--- a/dom/workers/ServiceWorkerManager.cpp
+++ b/dom/workers/ServiceWorkerManager.cpp
@@ -33,17 +33,16 @@
 #include "mozilla/BasePrincipal.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/ErrorNames.h"
 #include "mozilla/LoadContext.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/ContentChild.h"
-#include "mozilla/dom/DOMError.h"
 #include "mozilla/dom/ErrorEvent.h"
 #include "mozilla/dom/Headers.h"
 #include "mozilla/dom/InternalHeaders.h"
 #include "mozilla/dom/Navigator.h"
 #include "mozilla/dom/NotificationEvent.h"
 #include "mozilla/dom/PromiseNativeHandler.h"
 #include "mozilla/dom/Request.h"
 #include "mozilla/dom/RootedDictionary.h"
--- a/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js
+++ b/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js
@@ -98,18 +98,16 @@ var interfaceNamesInGlobalScope =
     "Crypto",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "CustomEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "Directory",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "DOMCursor",
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    "DOMError",
-// IMPORTANT: Do not change this list without review from a DOM peer!
     "DOMException",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "DOMRequest",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "DOMStringList",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "ErrorEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
--- a/dom/workers/test/test_worker_interfaces.js
+++ b/dom/workers/test/test_worker_interfaces.js
@@ -96,18 +96,16 @@ var interfaceNamesInGlobalScope =
     "CustomEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "DedicatedWorkerGlobalScope",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "Directory",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "DOMCursor",
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    "DOMError",
-// IMPORTANT: Do not change this list without review from a DOM peer!
     "DOMException",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "DOMRequest",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "DOMStringList",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "ErrorEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
deleted file mode 100644
--- a/testing/web-platform/meta/IndexedDB/error-attributes.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[error-attributes.html]
-  type: testharness
-  [IDBRequest and IDBTransaction error properties should be DOMExceptions]
-    expected: FAIL
-
--- a/testing/web-platform/meta/dom/historical.html.ini
+++ b/testing/web-platform/meta/dom/historical.html.ini
@@ -1,21 +1,10 @@
 [historical.html]
   type: testharness
-  [Historical DOM features must be removed: CDATASection]
-    expected: FAIL
-    bug: 660660
-
-  [Historical DOM features must be removed: DOMError]
-    expected: FAIL
-    bug: 1120178
-
-  [Historical DOM features must be removed: createCDATASection]
-    expected: FAIL
-    bug: 660660
-
   [Node member must be nuked: rootNode]
     disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1303802
     bug: 1269155
 
   [Historical DOM features must be removed: async]
     expected: FAIL
+    bug: 1328138
 
--- a/testing/web-platform/tests/IndexedDB/idbobjectstore_createIndex7-event_order.htm
+++ b/testing/web-platform/tests/IndexedDB/idbobjectstore_createIndex7-event_order.htm
@@ -1,16 +1,16 @@
 <!DOCTYPE html>
 <meta charset="utf-8">
 <title>IDBObjectStore.createIndex() - Event ordering for ConstraintError on request</title>
 <link rel="author" href="mailto:odinho@opera.com" title="Odin Hørthe Omdal">
 <meta rel=help href=http://odinho.html5.org/IndexedDB/spec/Overview.html#dfn-steps-for-aborting-a-transaction>
-<meta rel=assert title="Unless error was set to null, create a DOMError object and set its name to error. Set transaction's error property to this newly created DOMError.">
+<meta rel=assert title="Unless error was set to null, create a DOMException object and set its name to error. Set transaction's error property to this newly created DOMException.">
 <meta rel=assert title="If the transaction's request list contain any requests whose done flag is still false, abort the steps for asynchronously executing a request for each such request and queue a task to perform the following steps:">
-<meta rel=assert title="set the request's error attribute to a DOMError with a type of AbortError.">
+<meta rel=assert title="set the request's error attribute to a DOMException with a type of AbortError.">
 <meta rel=assert title="Dispatch an event at request. The event must use the Event interface and have its type set to 'error'. The event bubbles and is cancelable. The propagation path for the event is transaction's connection, then transaction and finally the request. There is no default action for the event.">
 <meta rel=assert title="Queue up an operation to dispatch an event at transaction. The event must use the Event interface and have its type set to 'abort'. The event does bubble but is not cancelable. The propagation path for the event is transaction's connection and then transaction.">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="support.js"></script>
 
 <script>
     // Transaction may fire window.onerror in some implementations.
--- a/toolkit/components/extensions/test/mochitest/test_ext_unlimitedStorage_legacy_persistent_indexedDB.html
+++ b/toolkit/components/extensions/test/mochitest/test_ext_unlimitedStorage_legacy_persistent_indexedDB.html
@@ -53,17 +53,17 @@ add_task(async function test_legacy_inde
             setTimeout(() => {
               reject(new Error("Timeout opening persistent db from background page"));
             }, PROMISE_RACE_TIMEOUT);
           }),
         ]);
 
         browser.test.notifyPass("indexeddb-storagePersistent-unlimitedStorage-done");
       } catch (error) {
-        const loggedError = error instanceof DOMError ? error.message : error;
+        const loggedError = error instanceof DOMException ? error.message : error;
         browser.test.fail(`error while testing persistent IndexedDB storage: ${loggedError}`);
         browser.test.notifyFail("indexeddb-storagePersistent-unlimitedStorage-done");
       }
     },
   });
 
   await extension.startup();
 
--- a/toolkit/components/thumbnails/PageThumbs.jsm
+++ b/toolkit/components/thumbnails/PageThumbs.jsm
@@ -73,17 +73,17 @@ XPCOMUtils.defineLazyModuleGetter(this, 
  * Utilities for dealing with promises and Task.jsm
  */
 const TaskUtils = {
   /**
    * Read the bytes from a blob, asynchronously.
    *
    * @return {Promise}
    * @resolve {ArrayBuffer} In case of success, the bytes contained in the blob.
-   * @reject {DOMError} In case of error, the underlying DOMError.
+   * @reject {DOMException} In case of error, the underlying DOMException.
    */
   readBlob: function readBlob(blob) {
     return new Promise((resolve, reject) => {
       let reader = new FileReader();
       reader.onloadend = function onloadend() {
         if (reader.readyState != FileReader.DONE) {
           reject(reader.error);
         } else {