Bug 870856 - Convert DOMError to WebIDL. r=Ms2ger, r=bz
authorAndrea Marchesini <amarchesini@mozilla.com>
Sat, 18 May 2013 13:52:06 -0400
changeset 143822 1196b497640b5281e428ec58a257eacc895fb367
parent 143821 321c5d4f88aa857963e5903b35828f0d7d994df9
child 143823 317fe0f314abf3ebb6c8fff3b69467083bd3a31c
child 143826 aad29aa892374b20bded7db2980c24f9e109d2d8
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMs2ger, bz
bugs870856
milestone24.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 870856 - Convert DOMError to WebIDL. r=Ms2ger, r=bz
content/base/public/nsIDOMFileReader.idl
content/base/src/FileIOObject.cpp
content/base/src/FileIOObject.h
content/base/src/nsDOMFileReader.cpp
dom/apps/src/Webapps.js
dom/base/DOMError.cpp
dom/base/DOMError.h
dom/base/DOMRequest.cpp
dom/base/DOMRequest.h
dom/base/moz.build
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/base/nsIDOMDOMError.idl
dom/base/nsIDOMDOMRequest.idl
dom/base/test/Makefile.in
dom/base/test/test_error.html
dom/bindings/Bindings.conf
dom/imptests/failures/webapps/DOMCore/tests/approved/test_interfaces.html.json
dom/indexedDB/IDBRequest.cpp
dom/indexedDB/IDBRequest.h
dom/indexedDB/IDBTransaction.cpp
dom/indexedDB/IDBTransaction.h
dom/indexedDB/IndexedDatabaseManager.cpp
dom/indexedDB/OpenDatabaseHelper.cpp
dom/indexedDB/nsIIDBRequest.idl
dom/indexedDB/nsIIDBTransaction.idl
dom/interfaces/apps/nsIDOMApplicationRegistry.idl
dom/network/src/TCPSocket.js
dom/telephony/TelephonyCall.cpp
dom/telephony/TelephonyCall.h
dom/telephony/nsIDOMTelephonyCall.idl
dom/webidl/DOMError.webidl
dom/webidl/DOMRequest.webidl
dom/webidl/WebIDL.mk
js/xpconnect/src/dom_quickstubs.qsconf
js/xpconnect/src/nsXPConnect.cpp
--- a/content/base/public/nsIDOMFileReader.idl
+++ b/content/base/public/nsIDOMFileReader.idl
@@ -2,19 +2,18 @@
 /* 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 "nsIDOMEventTarget.idl"
 
 interface nsIDOMEventListener;
 interface nsIDOMBlob;
-interface nsIDOMDOMError;
 
-[scriptable, builtinclass, uuid(81a8d00b-2982-44f6-aecf-faac0d0819d6)]
+[scriptable, builtinclass, uuid(39ea2c73-7711-4cea-9f73-3166c24dfa69)]
 interface nsIDOMFileReader : nsIDOMEventTarget
 {
   [implicit_jscontext]
   void readAsArrayBuffer(in nsIDOMBlob filedata);
   void readAsBinaryString(in nsIDOMBlob filedata);
   void readAsText(in nsIDOMBlob filedata, [optional] in DOMString encoding);
   void readAsDataURL(in nsIDOMBlob file);
 
@@ -22,17 +21,19 @@ interface nsIDOMFileReader : nsIDOMEvent
 
   const unsigned short EMPTY = 0;
   const unsigned short LOADING = 1;
   const unsigned short DONE = 2;
   readonly attribute unsigned short readyState;
 
   [implicit_jscontext]
   readonly attribute jsval result;
-  readonly attribute nsIDOMDOMError error;
+
+  // This is a DOMError
+  readonly attribute nsISupports error;
 
   [implicit_jscontext] attribute jsval onloadstart;
   [implicit_jscontext] attribute jsval onprogress;
   [implicit_jscontext] attribute jsval onload;
   [implicit_jscontext] attribute jsval onabort;
   [implicit_jscontext] attribute jsval onerror;
   [implicit_jscontext] attribute jsval onloadend;
 };
--- a/content/base/src/FileIOObject.cpp
+++ b/content/base/src/FileIOObject.cpp
@@ -80,23 +80,23 @@ FileIOObject::ClearProgressEventTimer()
 }
 
 void
 FileIOObject::DispatchError(nsresult rv, nsAString& finalEvent)
 {
   // Set the status attribute, and dispatch the error event
   switch (rv) {
   case NS_ERROR_FILE_NOT_FOUND:
-    mError = DOMError::CreateWithName(NS_LITERAL_STRING("NotFoundError"));
+    mError = new DOMError(GetOwner(), NS_LITERAL_STRING("NotFoundError"));
     break;
   case NS_ERROR_FILE_ACCESS_DENIED:
-    mError = DOMError::CreateWithName(NS_LITERAL_STRING("SecurityError"));
+    mError = new DOMError(GetOwner(), NS_LITERAL_STRING("SecurityError"));
     break;
   default:
-    mError = DOMError::CreateWithName(NS_LITERAL_STRING("NotReadableError"));
+    mError = new DOMError(GetOwner(), NS_LITERAL_STRING("NotReadableError"));
     break;
   }
 
   // Dispatch error event to signify load failure
   DispatchProgressEvent(NS_LITERAL_STRING(ERROR_STR));
   DispatchProgressEvent(finalEvent);
 }
 
@@ -226,17 +226,17 @@ FileIOObject::Abort(ErrorResult& aRv)
     return;
   }
 
   ClearProgressEventTimer();
 
   mReadyState = 2; // There are DONE constants on multiple interfaces,
                    // but they all have value 2.
   // XXX The spec doesn't say this
-  mError = DOMError::CreateWithName(NS_LITERAL_STRING("AbortError"));
+  mError = new DOMError(GetOwner(), NS_LITERAL_STRING("AbortError"));
 
   nsString finalEvent;
   DoAbort(finalEvent);
 
   // Dispatch the events
   DispatchProgressEvent(NS_LITERAL_STRING(ABORT_STR));
   DispatchProgressEvent(finalEvent);
 }
--- a/content/base/src/FileIOObject.h
+++ b/content/base/src/FileIOObject.h
@@ -38,17 +38,17 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
 
   // Common methods
   void Abort(ErrorResult& aRv);
   uint16_t ReadyState() const
   {
     return mReadyState;
   }
-  nsIDOMDOMError* GetError() const
+  DOMError* GetError() const
   {
     return mError;
   }
 
   NS_METHOD GetOnabort(JSContext* aCx, JS::Value* aValue);
   NS_METHOD SetOnabort(JSContext* aCx, const JS::Value& aValue);
   NS_METHOD GetOnerror(JSContext* aCx, JS::Value* aValue);
   NS_METHOD SetOnerror(JSContext* aCx, const JS::Value& aValue);
@@ -87,17 +87,17 @@ protected:
   void ClearProgressEventTimer();
   void DispatchError(nsresult rv, nsAString& finalEvent);
   nsresult DispatchProgressEvent(const nsAString& aType);
 
   nsCOMPtr<nsITimer> mProgressNotifier;
   bool mProgressEventWasDelayed;
   bool mTimerIsActive;
 
-  nsCOMPtr<nsIDOMDOMError> mError;
+  nsRefPtr<DOMError> mError;
   nsCOMPtr<nsIChannel> mChannel;
 
   uint16_t mReadyState;
 
   uint64_t mTotal;
   uint64_t mTransferred;
 };
 
--- a/content/base/src/nsDOMFileReader.cpp
+++ b/content/base/src/nsDOMFileReader.cpp
@@ -207,17 +207,17 @@ nsDOMFileReader::GetResult(JSContext* aC
   nsString tmpResult = mResult;
   if (!xpc::StringToJsval(aCx, tmpResult, aResult)) {
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMFileReader::GetError(nsIDOMDOMError** aError)
+nsDOMFileReader::GetError(nsISupports** aError)
 {
   NS_IF_ADDREF(*aError = GetError());
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMFileReader::ReadAsArrayBuffer(nsIDOMBlob* aFile, JSContext* aCx)
 {
--- a/dom/apps/src/Webapps.js
+++ b/dom/apps/src/Webapps.js
@@ -281,46 +281,16 @@ WebappsRegistry.prototype = {
                                                  Ci.mozIDOMApplicationRegistry2,
 #endif
                                                  ],
                                     flags: Ci.nsIClassInfo.DOM_OBJECT,
                                     classDescription: "Webapps Registry"})
 }
 
 /**
-  * nsIDOMDOMError object
-  */
-function createDOMError(aError) {
-  let error = Cc["@mozilla.org/dom-error;1"]
-                .createInstance(Ci.nsIDOMDOMError);
-  error.wrappedJSObject.init(aError);
-  return error;
-}
-
-function DOMError() {
-  this.wrappedJSObject = this;
-}
-
-DOMError.prototype = {
-  init: function domerror_init(aError) {
-    this.name = aError;
-  },
-
-  classID: Components.ID("{dcc1d5b7-43d8-4740-9244-b3d8db0f503d}"),
-
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMDOMError]),
-
-  classInfo: XPCOMUtils.generateCI({classID: Components.ID("{dcc1d5b7-43d8-4740-9244-b3d8db0f503d}"),
-                                    contractID: "@mozilla.org/dom-error;1",
-                                    interfaces: [Ci.nsIDOMDOMError],
-                                    flags: Ci.nsIClassInfo.DOM_OBJECT,
-                                    classDescription: "DOMError object"})
-}
-
-/**
   * mozIDOMApplication object
   */
 
 // A simple cache for the wrapped manifests.
 let manifestCache = {
   _cache: { },
 
   // Gets an entry from the cache, and populates the cache if needed.
@@ -454,17 +424,17 @@ WebappsApplication.prototype = {
     this._ondownloadapplied = aCallback;
   },
 
   get ondownloadapplied() {
     return this._ondownloadapplied;
   },
 
   get downloadError() {
-    return createDOMError(this._downloadError);
+    return new this._window.DOMError(this._downloadError || '');
   },
 
   download: function() {
     cpmm.sendAsyncMessage("Webapps:Download",
                           { manifestURL: this.manifestURL });
   },
 
   cancelDownload: function() {
@@ -781,10 +751,9 @@ WebappsApplicationMgmt.prototype = {
   classInfo: XPCOMUtils.generateCI({classID: Components.ID("{8c1bca96-266f-493a-8d57-ec7a95098c15}"),
                                     contractID: "@mozilla.org/webapps/application-mgmt;1",
                                     interfaces: [Ci.mozIDOMApplicationMgmt],
                                     flags: Ci.nsIClassInfo.DOM_OBJECT,
                                     classDescription: "Webapps Application Mgmt"})
 }
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([WebappsRegistry,
-                                                     WebappsApplication,
-                                                     DOMError]);
+                                                     WebappsApplication]);
--- a/dom/base/DOMError.cpp
+++ b/dom/base/DOMError.cpp
@@ -1,53 +1,75 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=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 "DOMError.h"
-
-#include "nsDOMClassInfo.h"
+#include "mozilla/dom/DOMError.h"
+#include "mozilla/dom/DOMErrorBinding.h"
+#include "nsContentUtils.h"
 #include "nsDOMException.h"
-
-using mozilla::dom::DOMError;
-
-namespace {
-
-struct NameMap
-{
-  uint16_t code;
-  const char* name;
-};
-
-} // anonymous namespace
+#include "nsPIDOMWindow.h"
 
-// static
-already_AddRefed<nsIDOMDOMError>
-DOMError::CreateForNSResult(nsresult aRv)
-{
-  const char* name;
-  const char* message;
-  aRv = NS_GetNameAndMessageForDOMNSResult(aRv, &name, &message);
-  if (NS_FAILED(aRv) || !name) {
-    return nullptr;
-  }
-  return CreateWithName(NS_ConvertASCIItoUTF16(name));
-}
+namespace mozilla {
+namespace dom {
 
-NS_IMPL_ADDREF(DOMError)
-NS_IMPL_RELEASE(DOMError)
-
-NS_INTERFACE_MAP_BEGIN(DOMError)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DOMError)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMDOMError)
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(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(nsISupports)
 NS_INTERFACE_MAP_END
 
-DOMCI_DATA(DOMError, DOMError)
+DOMError::DOMError(nsPIDOMWindow* aWindow, nsresult aValue)
+  : mWindow(aWindow)
+{
+  const char *name, *message;
+  NS_GetNameAndMessageForDOMNSResult(aValue, &name, &message);
+
+  mName = NS_ConvertASCIItoUTF16(name);
+  mMessage = NS_ConvertASCIItoUTF16(message);
+
+  SetIsDOMBinding();
+}
+
+DOMError::DOMError(nsPIDOMWindow* aWindow, const nsAString& aName)
+  : mWindow(aWindow)
+  , mName(aName)
+{
+  SetIsDOMBinding();
+}
 
-NS_IMETHODIMP
-DOMError::GetName(nsAString& aName)
+DOMError::DOMError(nsPIDOMWindow* aWindow, const nsAString& aName,
+                   const nsAString& aMessage)
+  : mWindow(aWindow)
+  , mName(aName)
+  , mMessage(aMessage)
+{
+  SetIsDOMBinding();
+}
+
+DOMError::~DOMError()
+{
+}
+
+JSObject*
+DOMError::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
 {
-  aName = mName;
-  return NS_OK;
+  return DOMErrorBinding::Wrap(aCx, aScope, this);
 }
+
+/* static */ already_AddRefed<DOMError>
+DOMError::Constructor(const GlobalObject& aGlobal, const nsAString& aName,
+                      const nsAString& aMessage, ErrorResult& aRv)
+{
+  nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.Get());
+
+  // Window is null for chrome code.
+
+  nsRefPtr<DOMError> ret = new DOMError(window, aName, aMessage);
+  return ret.forget();
+}
+
+} // namespace dom
+} // namespace mozilla
--- a/dom/base/DOMError.h
+++ b/dom/base/DOMError.h
@@ -2,47 +2,71 @@
 /* vim: set ts=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 "nsIDOMDOMError.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/ErrorResult.h"
+#include "mozilla/dom/BindingUtils.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsWrapperCache.h"
 
-#include "nsCOMPtr.h"
-#include "nsStringGlue.h"
+class nsPIDOMWindow;
 
 namespace mozilla {
 namespace dom {
 
-class DOMError : public nsIDOMDOMError
+class GlobalObject;
+
+class DOMError : public nsISupports,
+                 public nsWrapperCache
 {
+  nsCOMPtr<nsPIDOMWindow> mWindow;
   nsString mName;
+  nsString mMessage;
 
 public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIDOMDOMERROR
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMError)
 
-  static already_AddRefed<nsIDOMDOMError>
-  CreateForNSResult(nsresult rv);
+  // aWindow can be null if this DOMError is not associated with a particular
+  // window.
+
+  DOMError(nsPIDOMWindow* aWindow, nsresult aValue);
 
-  static already_AddRefed<nsIDOMDOMError>
-  CreateWithName(const nsAString& aName)
+  DOMError(nsPIDOMWindow* aWindow, const nsAString& aName);
+
+  DOMError(nsPIDOMWindow* aWindow, const nsAString& aName,
+           const nsAString& aMessage);
+
+  virtual ~DOMError();
+
+  nsPIDOMWindow* GetParentObject() const
   {
-    nsCOMPtr<nsIDOMDOMError> error = new DOMError(aName);
-    return error.forget();
+    return mWindow;
   }
 
-protected:
-  DOMError(const nsAString& aName)
-  : mName(aName)
-  { }
+  virtual JSObject*
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
+
+  static already_AddRefed<DOMError>
+  Constructor(const GlobalObject& global, const nsAString& name,
+              const nsAString& message, ErrorResult& aRv);
 
-  virtual ~DOMError()
-  { }
+  void GetName(nsString& aRetval) const
+  {
+    aRetval = mName;
+  }
+
+  void GetMessage(nsString& aRetval) const
+  {
+    aRetval = mMessage;
+  }
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_domerror_h__
--- a/dom/base/DOMRequest.cpp
+++ b/dom/base/DOMRequest.cpp
@@ -103,17 +103,17 @@ DOMRequest::GetReadyState(nsAString& aRe
 NS_IMETHODIMP
 DOMRequest::GetResult(JS::Value* aResult)
 {
   *aResult = Result();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-DOMRequest::GetError(nsIDOMDOMError** aError)
+DOMRequest::GetError(nsISupports** aError)
 {
   NS_IF_ADDREF(*aError = GetError());
   return NS_OK;
 }
 
 void
 DOMRequest::FireSuccess(JS::Handle<JS::Value> aResult)
 {
@@ -133,30 +133,30 @@ 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 == JSVAL_VOID, "mResult shouldn't have been set!");
 
   mDone = true;
-  mError = DOMError::CreateWithName(aError);
+  mError = new DOMError(GetOwner(), aError);
 
   FireEvent(NS_LITERAL_STRING("error"), true, true);
 }
 
 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 == JSVAL_VOID, "mResult shouldn't have been set!");
 
   mDone = true;
-  mError = DOMError::CreateForNSResult(aError);
+  mError = new DOMError(GetOwner(), aError);
 
   FireEvent(NS_LITERAL_STRING("error"), true, true);
 }
 
 void
 DOMRequest::FireEvent(const nsAString& aType, bool aBubble, bool aCancelable)
 {
   if (NS_FAILED(CheckInnerWindowCorrectness())) {
--- a/dom/base/DOMRequest.h
+++ b/dom/base/DOMRequest.h
@@ -3,32 +3,32 @@
 /* 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_domrequest_h__
 #define mozilla_dom_domrequest_h__
 
 #include "nsIDOMDOMRequest.h"
-#include "nsIDOMDOMError.h"
 #include "nsDOMEventTargetHelper.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/dom/DOMError.h"
 #include "mozilla/dom/DOMRequestBinding.h"
 
 #include "nsCOMPtr.h"
 
 namespace mozilla {
 namespace dom {
 
 class DOMRequest : public nsDOMEventTargetHelper,
                    public nsIDOMDOMRequest
 {
 protected:
   JS::Value mResult;
-  nsCOMPtr<nsIDOMDOMError> mError;
+  nsRefPtr<DOMError> mError;
   bool mDone;
   bool mRooted;
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMDOMREQUEST
   NS_REALLY_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper)
 
@@ -53,17 +53,17 @@ public:
 
   JS::Value Result(JSContext* = nullptr) const
   {
     NS_ASSERTION(mDone || mResult == JSVAL_VOID,
                "Result should be undefined when pending");
     return mResult;
   }
 
-  nsIDOMDOMError* GetError() const
+  DOMError* GetError() const
   {
     NS_ASSERTION(mDone || !mError,
                  "Error should be null when pending");
     return mError;
   }
 
   IMPL_EVENT_HANDLER(success)
   IMPL_EVENT_HANDLER(error)
--- a/dom/base/moz.build
+++ b/dom/base/moz.build
@@ -3,17 +3,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/.
 
 TEST_DIRS += ['test']
 
 XPIDL_SOURCES += [
     'nsIDOMDOMCursor.idl',
-    'nsIDOMDOMError.idl',
     'nsIDOMDOMRequest.idl',
     'nsIEntropyCollector.idl',
     'nsIScriptChannel.idl',
     'nsISiteSpecificUserAgent.idl',
 ]
 
 XPIDL_FLAGS += [
     '-I$(topsrcdir)/dom/interfaces/base',
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -313,17 +313,16 @@ using mozilla::dom::workers::ResolveWork
 #include "BluetoothAdapter.h"
 #include "BluetoothDevice.h"
 #endif
 
 #include "nsIDOMNavigatorSystemMessages.h"
 #include "DOMCameraManager.h"
 #include "DOMCameraControl.h"
 #include "DOMCameraCapabilities.h"
-#include "DOMError.h"
 #include "nsIOpenWindowEventDetail.h"
 #include "nsIAsyncScrollEventDetail.h"
 #include "nsIDOMGlobalObjectConstructor.h"
 #include "nsIDOMCanvasRenderingContext2D.h"
 #include "LockedFile.h"
 #include "GeneratedEvents.h"
 #include "nsDebug.h"
 
@@ -888,19 +887,16 @@ static nsDOMClassInfoData sClassInfoData
 
   NS_DEFINE_CLASSINFO_DATA(CameraManager, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(CameraControl, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(CameraCapabilities, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
-  NS_DEFINE_CLASSINFO_DATA(DOMError, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-
   NS_DEFINE_CLASSINFO_DATA(OpenWindowEventDetail, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(AsyncScrollEventDetail, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(LockedFile, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(CSSFontFeatureValuesRule, nsDOMGenericSH,
@@ -2262,20 +2258,16 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_BEGIN(CameraControl, nsICameraControl)
     DOM_CLASSINFO_MAP_ENTRY(nsICameraControl)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(CameraCapabilities, nsICameraCapabilities)
     DOM_CLASSINFO_MAP_ENTRY(nsICameraCapabilities)
   DOM_CLASSINFO_MAP_END
 
-  DOM_CLASSINFO_MAP_BEGIN(DOMError, nsIDOMDOMError)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMError)
-  DOM_CLASSINFO_MAP_END
-
   DOM_CLASSINFO_MAP_BEGIN(OpenWindowEventDetail, nsIOpenWindowEventDetail)
     DOM_CLASSINFO_MAP_ENTRY(nsIOpenWindowEventDetail)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(AsyncScrollEventDetail, nsIAsyncScrollEventDetail)
     DOM_CLASSINFO_MAP_ENTRY(nsIAsyncScrollEventDetail)
   DOM_CLASSINFO_MAP_END
 
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -223,17 +223,16 @@ DOMCI_CLASS(BluetoothManager)
 DOMCI_CLASS(BluetoothAdapter)
 DOMCI_CLASS(BluetoothDevice)
 #endif
 
 DOMCI_CLASS(CameraManager)
 DOMCI_CLASS(CameraControl)
 DOMCI_CLASS(CameraCapabilities)
 
-DOMCI_CLASS(DOMError)
 DOMCI_CLASS(OpenWindowEventDetail)
 DOMCI_CLASS(AsyncScrollEventDetail)
 
 DOMCI_CLASS(LockedFile)
 
 DOMCI_CLASS(CSSFontFeatureValuesRule)
 
 #ifdef MOZ_TIME_MANAGER
deleted file mode 100644
--- a/dom/base/nsIDOMDOMError.idl
+++ /dev/null
@@ -1,13 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=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 "nsISupports.idl"
-
-[scriptable, uuid(e4e28307-d409-4cf7-93cd-6ea8e889f87a)]
-interface nsIDOMDOMError : nsISupports
-{
-  readonly attribute DOMString name;
-};
--- a/dom/base/nsIDOMDOMRequest.idl
+++ b/dom/base/nsIDOMDOMRequest.idl
@@ -1,28 +1,29 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=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 "nsIDOMEventTarget.idl"
 
-interface nsIDOMDOMError;
 interface nsIDOMWindow;
 interface nsIDOMDOMCursor;
 interface nsICursorContinueCallback;
 
-[scriptable, builtinclass, uuid(e18fdde5-35b0-46df-8522-f88adf7698f3)]
+[scriptable, builtinclass, uuid(d4c7372a-661c-4798-9a13-af48128609e9)]
 interface nsIDOMDOMRequest : nsIDOMEventTarget
 {
   readonly attribute DOMString readyState; // "pending" or "done"
 
   readonly attribute jsval result;
-  readonly attribute nsIDOMDOMError error;
+
+  // DOMError
+  readonly attribute nsISupports error;
 
   [implicit_jscontext] attribute jsval onsuccess;
   [implicit_jscontext] attribute jsval onerror;
 };
 
 [scriptable, builtinclass, uuid(060df968-fd71-47ca-91a8-6b64dadceb2c)]
 interface nsIDOMRequestService : nsISupports
 {
--- a/dom/base/test/Makefile.in
+++ b/dom/base/test/Makefile.in
@@ -25,16 +25,17 @@ MOCHITEST_FILES = \
   test_window_enumeration.html \
   test_window_extensible.html \
   test_window_indexing.html \
   test_writable-replaceable.html \
   test_domcursor.html \
   test_named_frames.html \
   test_Image_constructor.html \
   test_setting_opener.html \
+  test_error.html \
   $(NULL)
 
 MOCHITEST_CHROME_FILES = \
    test_bug715041.xul \
    test_bug715041_removal.xul \
    $(NULL)
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/dom/base/test/test_error.html
@@ -0,0 +1,44 @@
+
+<!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/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -1545,17 +1545,16 @@ def addExternalHTMLElement(element):
 
 addExternalHTMLElement('HTMLFormElement')
 addExternalIface('ActivityOptions', nativeType='nsIDOMMozActivityOptions',
                  headerFile='nsIDOMActivityOptions.h')
 addExternalIface('Counter')
 addExternalIface('CSSRule')
 addExternalIface('DeviceAcceleration', headerFile='nsIDOMDeviceMotionEvent.h', notflattened=True)
 addExternalIface('DeviceRotationRate', headerFile='nsIDOMDeviceMotionEvent.h', notflattened=True)
-addExternalIface('DOMError')
 addExternalIface('CSSRuleList')
 addExternalIface('DOMStringList')
 addExternalIface('RTCDataChannel', nativeType='nsIDOMDataChannel')
 addExternalIface('File')
 addExternalIface('FileCallback', nativeType='nsIFileCallback',
                  headerFile='nsIDOMHTMLCanvasElement.h')
 addExternalIface('HitRegionOptions', nativeType='nsISupports')
 addExternalIface('IDBOpenDBRequest', nativeType='nsIIDBOpenDBRequest')
--- a/dom/imptests/failures/webapps/DOMCore/tests/approved/test_interfaces.html.json
+++ b/dom/imptests/failures/webapps/DOMCore/tests/approved/test_interfaces.html.json
@@ -24,21 +24,16 @@
   "DOMException exception: constant NETWORK_ERR on exception interface prototype object": true,
   "DOMException exception: constant ABORT_ERR on exception interface prototype object": true,
   "DOMException exception: constant URL_MISMATCH_ERR on exception interface prototype object": true,
   "DOMException exception: constant QUOTA_EXCEEDED_ERR on exception interface prototype object": true,
   "DOMException exception: constant TIMEOUT_ERR on exception interface prototype object": true,
   "DOMException exception: constant INVALID_NODE_TYPE_ERR on exception interface prototype object": true,
   "DOMException exception: constant DATA_CLONE_ERR on exception interface prototype object": true,
   "DOMException exception: field code on exception interface prototype object": true,
-  "DOMError interface: existence and properties of interface object": true,
-  "DOMError interface constructor": true,
-  "DOMError interface: existence and properties of interface prototype object": true,
-  "DOMError interface: existence and properties of interface prototype object's \"constructor\" property": true,
-  "DOMError interface: attribute name": true,
   "Event interface: document.createEvent(\"Event\") must have own property \"isTrusted\"": true,
   "Event interface: document.createEvent(\"Event\") must inherit property \"timeStamp\" with the proper type (15)": true,
   "Event interface: new Event(\"foo\") must have own property \"isTrusted\"": true,
   "Event interface: new Event(\"foo\") must inherit property \"timeStamp\" with the proper type (15)": true,
   "CustomEvent interface: existence and properties of interface object": true,
   "CustomEvent interface constructor": true,
   "CustomEvent interface: existence and properties of interface prototype object": true,
   "CustomEvent interface: existence and properties of interface prototype object's \"constructor\" property": true,
--- a/dom/indexedDB/IDBRequest.cpp
+++ b/dom/indexedDB/IDBRequest.cpp
@@ -18,17 +18,16 @@
 #include "nsStringGlue.h"
 #include "nsThreadUtils.h"
 #include "nsWrapperCacheInlines.h"
 
 #include "AsyncConnectionHelper.h"
 #include "IDBEvents.h"
 #include "IDBFactory.h"
 #include "IDBTransaction.h"
-#include "DOMError.h"
 
 namespace {
 
 #ifdef MOZ_ENABLE_PROFILER_SPS
 uint64_t gNextSerialNumber = 1;
 #endif
 
 } // anonymous namespace
@@ -159,17 +158,17 @@ IDBRequest::NotifyHelperSentResultsToChi
 
 void
 IDBRequest::SetError(nsresult aRv)
 {
   NS_ASSERTION(NS_FAILED(aRv), "Er, what?");
   NS_ASSERTION(!mError, "Already have an error?");
 
   mHaveResultOrErrorCode = true;
-  mError = DOMError::CreateForNSResult(aRv);
+  mError = new mozilla::dom::DOMError(GetOwner(), aRv);
   mErrorCode = aRv;
 
   mResultVal = JSVAL_VOID;
 }
 
 #ifdef DEBUG
 nsresult
 IDBRequest::GetErrorCode() const
@@ -273,27 +272,36 @@ IDBRequest::GetResult(jsval* aResult)
     // XXX Need a real error code here.
     return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
   }
 
   *aResult = mResultVal;
   return NS_OK;
 }
 
-NS_IMETHODIMP
-IDBRequest::GetError(nsIDOMDOMError** aError)
+mozilla::dom::DOMError*
+IDBRequest::GetError(mozilla::ErrorResult& aRv)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (!mHaveResultOrErrorCode) {
-    return NS_ERROR_DOM_INVALID_STATE_ERR;
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+    return nullptr;
   }
 
-  NS_IF_ADDREF(*aError = mError);
-  return NS_OK;
+  return mError;
+}
+
+NS_IMETHODIMP
+IDBRequest::GetError(nsISupports** aError)
+{
+  ErrorResult rv;
+  *aError = GetError(rv);
+  NS_IF_ADDREF(*aError);
+  return rv.ErrorCode();
 }
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBRequest, IDBWrapperCache)
   // Don't need NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS because
   // nsDOMEventTargetHelper does it for us.
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSource)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTransaction)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
--- a/dom/indexedDB/IDBRequest.h
+++ b/dom/indexedDB/IDBRequest.h
@@ -8,16 +8,17 @@
 #define mozilla_dom_indexeddb_idbrequest_h__
 
 #include "mozilla/dom/indexedDB/IndexedDatabase.h"
 
 #include "nsIIDBRequest.h"
 #include "nsIIDBOpenDBRequest.h"
 #include "nsDOMEventTargetHelper.h"
 #include "mozilla/dom/indexedDB/IDBWrapperCache.h"
+#include "mozilla/dom/DOMError.h"
 
 class nsIScriptContext;
 class nsPIDOMWindow;
 
 BEGIN_INDEXEDDB_NAMESPACE
 
 class HelperBase;
 class IDBFactory;
@@ -59,16 +60,18 @@ public:
 #ifdef DEBUG
   ;
 #else
   {
     return mErrorCode;
   }
 #endif
 
+  DOMError* GetError(ErrorResult& aRv);
+
   JSContext* GetJSContext();
 
   void
   SetActor(IndexedDBRequestParentBase* aActorParent)
   {
     NS_ASSERTION(!aActorParent || !mActorParent,
                  "Shouldn't have more than one!");
     mActorParent = aActorParent;
@@ -101,17 +104,17 @@ public:
 protected:
   IDBRequest();
   ~IDBRequest();
 
   nsCOMPtr<nsISupports> mSource;
   nsRefPtr<IDBTransaction> mTransaction;
 
   jsval mResultVal;
-  nsCOMPtr<nsIDOMDOMError> mError;
+  nsRefPtr<mozilla::dom::DOMError> mError;
   IndexedDBRequestParentBase* mActorParent;
   nsString mFilename;
 #ifdef MOZ_ENABLE_PROFILER_SPS
   uint64_t mSerialNumber;
 #endif
   nsresult mErrorCode;
   uint32_t mLineNo;
   bool mHaveResultOrErrorCode;
@@ -133,16 +136,21 @@ public:
          JS::Handle<JSObject*> aScriptOwner,
          JSContext* aCallingCx);
 
   void SetTransaction(IDBTransaction* aTransaction);
 
   // nsIDOMEventTarget
   virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
 
+  DOMError* GetError(ErrorResult& aRv)
+  {
+    return IDBRequest::GetError(aRv);
+  }
+
   IDBFactory*
   Factory() const
   {
     return mFactory;
   }
 
 protected:
   ~IDBOpenDBRequest();
--- a/dom/indexedDB/IDBTransaction.cpp
+++ b/dom/indexedDB/IDBTransaction.cpp
@@ -6,17 +6,16 @@
 
 #include "base/basictypes.h"
 
 #include "IDBTransaction.h"
 
 #include "nsIAppShell.h"
 #include "nsIScriptContext.h"
 
-#include "DOMError.h"
 #include "mozilla/dom/quota/QuotaManager.h"
 #include "mozilla/storage.h"
 #include "nsContentUtils.h"
 #include "nsDOMClassInfoID.h"
 #include "nsDOMLists.h"
 #include "nsEventDispatcher.h"
 #include "nsPIDOMWindow.h"
 #include "nsProxyRelease.h"
@@ -32,16 +31,17 @@
 #include "IndexedDatabaseManager.h"
 #include "ProfilerHelpers.h"
 #include "TransactionThreadPool.h"
 
 #include "ipc/IndexedDBChild.h"
 
 #define SAVEPOINT_NAME "savepoint"
 
+using namespace mozilla::dom;
 USING_INDEXEDDB_NAMESPACE
 using mozilla::dom::quota::QuotaManager;
 
 namespace {
 
 NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
 
 #ifdef MOZ_ENABLE_PROFILER_SPS
@@ -510,21 +510,21 @@ IDBTransaction::AddFileInfo(nsIDOMBlob* 
 void
 IDBTransaction::ClearCreatedFileInfos()
 {
   mCreatedFileInfos.Clear();
 }
 
 nsresult
 IDBTransaction::AbortInternal(nsresult aAbortCode,
-                              already_AddRefed<nsIDOMDOMError> aError)
+                              already_AddRefed<DOMError> aError)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
-  nsCOMPtr<nsIDOMDOMError> error = aError;
+  nsRefPtr<DOMError> error = aError;
 
   if (IsFinished()) {
     return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
   }
 
   if (mActorChild) {
     NS_ASSERTION(!IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
     mActorChild->SendAbort(aAbortCode);
@@ -581,28 +581,29 @@ IDBTransaction::AbortInternal(nsresult a
 }
 
 nsresult
 IDBTransaction::Abort(IDBRequest* aRequest)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(aRequest, "This is undesirable.");
 
-  nsCOMPtr<nsIDOMDOMError> error;
-  aRequest->GetError(getter_AddRefs(error));
+  ErrorResult rv;
+  nsRefPtr<DOMError> error = aRequest->GetError(rv);
 
   return AbortInternal(aRequest->GetErrorCode(), error.forget());
 }
 
 nsresult
 IDBTransaction::Abort(nsresult aErrorCode)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
-  return AbortInternal(aErrorCode, DOMError::CreateForNSResult(aErrorCode));
+  nsRefPtr<DOMError> error = new DOMError(GetOwner(), aErrorCode);
+  return AbortInternal(aErrorCode, error.forget());
 }
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBTransaction,
                                                   IDBWrapperCache)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDatabase)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mError)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCreatedObjectStores)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDeletedObjectStores)
@@ -660,17 +661,17 @@ IDBTransaction::GetMode(nsAString& aMode
       NS_NOTREACHED("Bad mode value!");
       return NS_ERROR_UNEXPECTED;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-IDBTransaction::GetError(nsIDOMDOMError** aError)
+IDBTransaction::GetError(nsISupports** aError)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (IsOpen()) {
     return NS_ERROR_DOM_INVALID_STATE_ERR;
   }
 
   NS_IF_ADDREF(*aError = mError);
@@ -853,17 +854,17 @@ CommitHelper::Run()
                                  NS_LITERAL_STRING(ABORT_EVT_STR),
                                  eDoesBubble, eNotCancelable);
 
       // The transaction may already have an error object (e.g. if one of the
       // requests failed).  If it doesn't, and it wasn't aborted
       // programmatically, create one now.
       if (!mTransaction->mError &&
           mAbortCode != NS_ERROR_DOM_INDEXEDDB_ABORT_ERR) {
-        mTransaction->mError = DOMError::CreateForNSResult(mAbortCode);
+        mTransaction->mError = new DOMError(mTransaction->GetOwner(), mAbortCode);
       }
     }
     else {
       event = CreateGenericEvent(mTransaction,
                                  NS_LITERAL_STRING(COMPLETE_EVT_STR),
                                  eDoesNotBubble, eNotCancelable);
     }
     NS_ENSURE_TRUE(event, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
--- a/dom/indexedDB/IDBTransaction.h
+++ b/dom/indexedDB/IDBTransaction.h
@@ -8,17 +8,17 @@
 #define mozilla_dom_indexeddb_idbtransaction_h__
 
 #include "mozilla/dom/indexedDB/IndexedDatabase.h"
 
 #include "mozIStorageConnection.h"
 #include "mozIStorageStatement.h"
 #include "mozIStorageFunction.h"
 #include "nsIIDBTransaction.h"
-#include "nsIDOMDOMError.h"
+#include "mozilla/dom/DOMError.h"
 #include "nsIRunnable.h"
 
 #include "nsAutoPtr.h"
 #include "nsClassHashtable.h"
 #include "nsHashKeys.h"
 #include "nsInterfaceHashtable.h"
 #include "nsRefPtrHashtable.h"
 
@@ -217,34 +217,35 @@ public:
   GetSerialNumber() const
   {
     return mSerialNumber;
   }
 #endif
 
 private:
   nsresult
-  AbortInternal(nsresult aAbortCode, already_AddRefed<nsIDOMDOMError> aError);
+  AbortInternal(nsresult aAbortCode,
+                already_AddRefed<mozilla::dom::DOMError> aError);
 
   // Should only be called directly through IndexedDBDatabaseChild.
   static already_AddRefed<IDBTransaction>
   CreateInternal(IDBDatabase* aDatabase,
                  nsTArray<nsString>& aObjectStoreNames,
                  Mode aMode,
                  bool aDispatchDelayed,
                  bool aIsVersionChangeTransactionChild);
 
   IDBTransaction();
   ~IDBTransaction();
 
   nsresult CommitOrRollback();
 
   nsRefPtr<IDBDatabase> mDatabase;
   nsRefPtr<DatabaseInfo> mDatabaseInfo;
-  nsCOMPtr<nsIDOMDOMError> mError;
+  nsRefPtr<DOMError> mError;
   nsTArray<nsString> mObjectStoreNames;
   ReadyState mReadyState;
   Mode mMode;
   uint32_t mPendingRequests;
 
   nsInterfaceHashtable<nsCStringHashKey, mozIStorageStatement>
     mCachedStatements;
 
--- a/dom/indexedDB/IndexedDatabaseManager.cpp
+++ b/dom/indexedDB/IndexedDatabaseManager.cpp
@@ -234,24 +234,25 @@ IndexedDatabaseManager::FireWindowOnErro
 
   nsCOMPtr<EventTarget> eventTarget =
     aVisitor.mDOMEvent->InternalDOMEvent()->GetTarget();
 
   nsCOMPtr<nsIIDBRequest> strongRequest = do_QueryInterface(eventTarget);
   IDBRequest* request = static_cast<IDBRequest*>(strongRequest.get());
   NS_ENSURE_TRUE(request, NS_ERROR_UNEXPECTED);
 
-  nsCOMPtr<nsIDOMDOMError> error;
-  rv = request->GetError(getter_AddRefs(error));
-  NS_ENSURE_SUCCESS(rv, rv);
+  ErrorResult ret;
+  nsRefPtr<DOMError> error = request->GetError(ret);
+  if (ret.Failed()) {
+    return ret.ErrorCode();
+  }
 
   nsString errorName;
   if (error) {
-    rv = error->GetName(errorName);
-    NS_ENSURE_SUCCESS(rv, rv);
+    error->GetName(errorName);
   }
 
   nsScriptErrorEvent event(true, NS_LOAD_ERROR);
   request->FillScriptErrorEvent(&event);
   NS_ABORT_IF_FALSE(event.fileName,
                     "FillScriptErrorEvent should give us a non-null string "
                     "for our error's fileName");
 
--- a/dom/indexedDB/OpenDatabaseHelper.cpp
+++ b/dom/indexedDB/OpenDatabaseHelper.cpp
@@ -2415,20 +2415,20 @@ OpenDatabaseHelper::DispatchErrorEvent()
   nsRefPtr<nsIDOMEvent> event =
     CreateGenericEvent(mOpenDBRequest, NS_LITERAL_STRING(ERROR_EVT_STR),
                        eDoesBubble, eCancelable);
   if (!event) {
     NS_ERROR("Failed to create event!");
     return;
   }
 
-  nsCOMPtr<nsIDOMDOMError> error;
-  DebugOnly<nsresult> rv =
-    mOpenDBRequest->GetError(getter_AddRefs(error));
-  NS_ASSERTION(NS_SUCCEEDED(rv), "This shouldn't be failing at this point!");
+  ErrorResult rv;
+  nsRefPtr<DOMError> error = mOpenDBRequest->GetError(rv);
+
+  NS_ASSERTION(!rv.Failed(), "This shouldn't be failing at this point!");
   if (!error) {
     mOpenDBRequest->SetError(mResultCode);
   }
 
   bool dummy;
   mOpenDBRequest->DispatchEvent(event, &dummy);
 }
 
--- a/dom/indexedDB/nsIIDBRequest.idl
+++ b/dom/indexedDB/nsIIDBRequest.idl
@@ -1,31 +1,31 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=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 "nsISupports.idl"
 
-interface nsIDOMDOMError;
 interface nsIDOMEventListener;
 interface nsIIDBTransaction;
 
 /**
  * IDBRequest interface.  See
  * http://dev.w3.org/2006/webapi/WebSimpleDB/#idl-def-IDBRequest for more
  * information.
  */
-[scriptable, builtinclass, uuid(006f39d6-342e-4935-a438-365611fd9491)]
+[scriptable, builtinclass, uuid(4d1e9ee3-4bd0-4c99-9e6a-19cb536ab6d4)]
 interface nsIIDBRequest : nsISupports
 {
   readonly attribute jsval result;
 
-  readonly attribute nsIDOMDOMError error;
+  // This is a DOMError
+  readonly attribute nsISupports error;
 
   readonly attribute nsISupports source;
 
   readonly attribute nsIIDBTransaction transaction;
 
   // "pending" or "done"
   readonly attribute DOMString readyState;
 
--- a/dom/indexedDB/nsIIDBTransaction.idl
+++ b/dom/indexedDB/nsIIDBTransaction.idl
@@ -6,32 +6,32 @@
 
 #include "nsISupports.idl"
 
 interface nsIDOMEventListener;
 interface nsIIDBObjectStore;
 interface nsIIDBRequest;
 interface nsIIDBDatabase;
 interface nsIDOMDOMStringList;
-interface nsIDOMDOMError;
 
 /**
  * IDBDTransaction interface.  See
  * http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBTransaction
  * for more information.
  */
-[scriptable, builtinclass, uuid(3197172b-2f56-4837-9427-5e5d4b20a363)]
+[scriptable, builtinclass, uuid(e17e36f6-a7d8-40b7-82d4-b54847169834)]
 interface nsIIDBTransaction : nsISupports
 {
   readonly attribute nsIIDBDatabase db;
 
   // "readonly", "readwrite" or "versionchange"
   readonly attribute DOMString mode;
 
-  readonly attribute nsIDOMDOMError error;
+  // This is a DOMError
+  readonly attribute nsISupports error;
 
   readonly attribute nsIDOMDOMStringList objectStoreNames;
 
   nsIIDBObjectStore
   objectStore([Null(Stringify)] in DOMString name);
 
   // Don't commit the transaction.
   void abort();
--- a/dom/interfaces/apps/nsIDOMApplicationRegistry.idl
+++ b/dom/interfaces/apps/nsIDOMApplicationRegistry.idl
@@ -1,19 +1,18 @@
 /* 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 "domstubs.idl"
 #include "nsIDOMEventTarget.idl"
 
 interface nsIDOMDOMRequest;
-interface nsIDOMDOMError;
 
-[scriptable, uuid(d89870fe-5ba3-11e2-a5d2-cfa1d3f6e5f4)]
+[scriptable, uuid(d33ee8a0-00e4-4669-b55d-f77fbee1153d)]
 interface mozIDOMApplication  : nsISupports
 {
   readonly attribute jsval manifest;
   readonly attribute jsval updateManifest;
   readonly attribute DOMString manifestURL;
   readonly attribute jsval receipts; /* an array of strings */
   readonly attribute DOMString origin;
   readonly attribute DOMString installOrigin;
@@ -55,17 +54,18 @@ interface mozIDOMApplication  : nsISuppo
    */
   nsIDOMDOMRequest checkForUpdate();
 
   readonly attribute boolean downloadAvailable;
   readonly attribute boolean downloading;
   readonly attribute boolean readyToApplyDownload;
   readonly attribute long downloadSize;
 
-  readonly attribute nsIDOMDOMError downloadError;
+  // This is a DOMError
+  readonly attribute nsISupports downloadError;
 
   attribute nsIDOMEventListener ondownloadsuccess;
   attribute nsIDOMEventListener ondownloaderror;
   attribute nsIDOMEventListener ondownloadavailable;
 
   /**
    * Will fire once the mgmt.applyDownload() call succeeds.
    */
--- a/dom/network/src/TCPSocket.js
+++ b/dom/network/src/TCPSocket.js
@@ -35,21 +35,18 @@ const kCLOSED = 'closed';
 
 const BUFFER_SIZE = 65536;
 
 // XXX we have no TCPError implementation right now because it's really hard to
 // do on b2g18.  On mozilla-central we want a proper TCPError that ideally
 // sub-classes DOMError.  Bug 867872 has been filed to implement this and
 // contains a documented TCPError.webidl that maps all the error codes we use in
 // this file to slightly more readable explanations.
-function createTCPError(aErrorName, aErrorType) {
-  let error = Cc["@mozilla.org/dom-error;1"]
-                .createInstance(Ci.nsIDOMDOMError);
-  error.wrappedJSObject.init(aErrorName);
-  return error;
+function createTCPError(aWindow, aErrorName, aErrorType) {
+  return new (aWindow ? aWindow.DOMError : DOMError)(aErrorName);
 }
 
 
 /*
  * Debug logging function
  */
 
 let debug = false;
@@ -267,17 +264,17 @@ TCPSocket.prototype = {
 
     this["on" + type].call(null, new TCPSocketEvent(type, this, data || ""));
   },
 
   /* nsITCPSocketInternal methods */
   callListenerError: function ts_callListenerError(type, name) {
     // XXX we're not really using TCPError at this time, so there's only a name
     // attribute to pass.
-    this.callListener(type, createTCPError(name));
+    this.callListener(type, createTCPError(this.useWin, name));
   },
 
   callListenerData: function ts_callListenerString(type, data) {
     this.callListener(type, data);
   },
 
   callListenerArrayBuffer: function ts_callListenerArrayBuffer(type, data) {
     this.callListener(type, data);
@@ -630,17 +627,17 @@ TCPSocket.prototype = {
           case 0x804B0047: // NS_ERROR_NET_INTERRUPT, network(71)
             errName = 'NetworkInterruptError';
             break;
           default:
             errName = 'NetworkError';
             break;
         }
       }
-      let err = createTCPError(errName, errType);
+      let err = createTCPError(this.useWin, errName, errType);
       this.callListener("error", err);
     }
     this.callListener("close");
   },
 
   // nsITransportEventSink (Triggered by transport.setEventSink)
   onTransportStatus: function ts_onTransportStatus(
     transport, status, progress, max) {
--- a/dom/telephony/TelephonyCall.cpp
+++ b/dom/telephony/TelephonyCall.cpp
@@ -3,17 +3,17 @@
 /* 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 "TelephonyCall.h"
 
 #include "nsIDOMCallEvent.h"
 
-#include "DOMError.h"
+#include "mozilla/dom/DOMError.h"
 #include "GeneratedEvents.h"
 #include "nsDOMClassInfo.h"
 #include "Telephony.h"
 #include "nsITelephonyProvider.h"
 
 USING_TELEPHONY_NAMESPACE
 
 // static
@@ -144,17 +144,17 @@ TelephonyCall::DispatchCallEvent(const n
 }
 
 void
 TelephonyCall::NotifyError(const nsAString& aError)
 {
   // Set the error string
   NS_ASSERTION(!mError, "Already have an error?");
 
-  mError = DOMError::CreateWithName(aError);
+  mError = new mozilla::dom::DOMError(GetOwner(), aError);
 
   // Do the state transitions
   ChangeStateInternal(nsITelephonyProvider::CALL_STATE_DISCONNECTED, true);
 
   nsresult rv = DispatchCallEvent(NS_LITERAL_STRING("error"), this);
   if (NS_FAILED(rv)) {
     NS_WARNING("Failed to dispatch error event!");
   }
@@ -191,17 +191,17 @@ TelephonyCall::GetState(nsAString& aStat
 NS_IMETHODIMP
 TelephonyCall::GetEmergency(bool* aEmergency)
 {
   *aEmergency = mEmergency;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-TelephonyCall::GetError(nsIDOMDOMError** aError)
+TelephonyCall::GetError(nsISupports** aError)
 {
   NS_IF_ADDREF(*aError = mError);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TelephonyCall::Answer()
 {
--- a/dom/telephony/TelephonyCall.h
+++ b/dom/telephony/TelephonyCall.h
@@ -5,30 +5,31 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_telephony_telephonycall_h__
 #define mozilla_dom_telephony_telephonycall_h__
 
 #include "TelephonyCommon.h"
 
 #include "nsIDOMTelephonyCall.h"
+#include "mozilla/dom/DOMError.h"
 
 class nsPIDOMWindow;
 
 BEGIN_TELEPHONY_NAMESPACE
 
 class TelephonyCall : public nsDOMEventTargetHelper,
                       public nsIDOMTelephonyCall
 {
   nsRefPtr<Telephony> mTelephony;
 
   nsString mNumber;
   nsString mState;
   bool mEmergency;
-  nsCOMPtr<nsIDOMDOMError> mError;
+  nsRefPtr<mozilla::dom::DOMError> mError;
 
   uint32_t mCallIndex;
   uint16_t mCallState;
   bool mLive;
   bool mOutgoing;
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
--- a/dom/telephony/nsIDOMTelephonyCall.idl
+++ b/dom/telephony/nsIDOMTelephonyCall.idl
@@ -1,32 +1,32 @@
 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
 /* vim: set ts=2 et sw=2 tw=40: */
 /* 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 "nsIDOMEventTarget.idl"
-#include "nsIDOMDOMError.idl"
 
 interface nsIDOMEventListener;
 
-[scriptable, builtinclass, uuid(f0a25998-b0a9-11e2-82d2-60a44c237d2b)]
+[scriptable, builtinclass, uuid(22e44e8c-cb74-44f2-abe6-b37e9f42ea79)]
 interface nsIDOMTelephonyCall : nsIDOMEventTarget
 {
   readonly attribute DOMString number;
 
   readonly attribute DOMString state;
 
   // The property "emergency" indicate whether the call number is an emergency
   // number. Only the outgoing call could have a value with true and it is
   // available after dialing state.
   readonly attribute boolean emergency;
 
-  readonly attribute nsIDOMDOMError error;
+  // This is a DOMError
+  readonly attribute nsISupports error;
 
   void answer();
   void hangUp();
   void hold();
   void resume();
 
   [implicit_jscontext] attribute jsval onstatechange;
 
--- a/dom/webidl/DOMError.webidl
+++ b/dom/webidl/DOMError.webidl
@@ -1,15 +1,20 @@
 /* -*- 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://www.w3.org/TR/2012/WD-dom-20120105/
+ * 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 = "")]
 interface DOMError {
+  [Constant]
   readonly attribute DOMString name;
+
+  [Constant]
+  readonly attribute DOMString message;
 };
--- a/dom/webidl/DOMRequest.webidl
+++ b/dom/webidl/DOMRequest.webidl
@@ -1,14 +1,13 @@
 /* -*- 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/. */
 
-interface DOMError;
 interface Window;
 
 enum DOMRequestReadyState { "pending", "done" };
 
 interface DOMRequest : EventTarget {
   readonly attribute DOMRequestReadyState readyState;
 
   readonly attribute any result;
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -53,16 +53,17 @@ webidl_files = \
   DelayNode.webidl \
   DesktopNotification.webidl \
   DeviceMotionEvent.webidl \
   DeviceStorage.webidl \
   Document.webidl \
   DocumentFragment.webidl \
   DocumentType.webidl \
   DOMCursor.webidl \
+  DOMError.webidl \
   DOMImplementation.webidl \
   DOMParser.webidl \
   DOMRequest.webidl \
   DOMSettableTokenList.webidl \
   DOMStringMap.webidl \
   DOMTokenList.webidl \
   DOMTransaction.webidl \
   DragEvent.webidl \
--- a/js/xpconnect/src/dom_quickstubs.qsconf
+++ b/js/xpconnect/src/dom_quickstubs.qsconf
@@ -109,18 +109,16 @@ members = [
     'nsIIDBKeyRange.*',
     'nsIIDBObjectStore.*',
     'nsIIDBRequest.*',
     'nsIIDBTransaction.*',
     'nsIIDBOpenDBRequest.*',
     'nsIIDBVersionChangeEvent.*',
     'nsIIndexedDatabaseManager.*',
 
-    'nsIDOMDOMError.*',
-
     # dom/file
     'nsIDOMLockedFile.*',
 
     # dom/quota
     'nsIQuotaManager.*',
     'nsIQuotaRequest.*',
     'nsIUsageCallback.*',
     ]
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -32,16 +32,17 @@
 #include "jsdIDebuggerService.h"
 #endif
 
 #include "XPCQuickStubs.h"
 
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/TextDecoderBinding.h"
 #include "mozilla/dom/TextEncoderBinding.h"
+#include "mozilla/dom/DOMErrorBinding.h"
 
 #include "nsWrapperCacheInlines.h"
 #include "nsCycleCollector.h"
 #include "nsCycleCollectorUtils.h"
 #include "nsDOMMutationObserver.h"
 #include "nsICycleCollectorListener.h"
 #include "nsThread.h"
 #include "mozilla/XPTInterfaceInfoManager.h"
@@ -1091,17 +1092,18 @@ nsXPConnect::InitClassesWithNewWrappedGl
 
     // Stuff coming through this path always ends up as a DOM global.
     // XXX Someone who knows why we can assert this should re-check
     //     (after bug 720580).
     MOZ_ASSERT(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL);
 
     // Init WebIDL binding constructors wanted on all XPConnect globals.
     if (!TextDecoderBinding::GetConstructorObject(aJSContext, global) ||
-        !TextEncoderBinding::GetConstructorObject(aJSContext, global)) {
+        !TextEncoderBinding::GetConstructorObject(aJSContext, global) ||
+        !DOMErrorBinding::GetConstructorObject(aJSContext, global)) {
         return UnexpectedFailure(NS_ERROR_FAILURE);
     }
 
     wrappedGlobal.forget(_retval);
     return NS_OK;
 }
 
 nsresult