Bug 730161 - Implement IDBRequest.error. r=sicking
authorMasatoshi Kimura <VYV03354@nifty.ne.jp>
Wed, 11 Apr 2012 17:55:21 -0400
changeset 91464 37e9c8655cfd13883b22ac54490f6f9a0b5a636e
parent 91463 0e03eb171e0869596901d795e95077fb39d16a14
child 91465 3b27921b99ebc4e6d374856aee3fcfcabfcc5864
push id22445
push usereakhgari@mozilla.com
push dateThu, 12 Apr 2012 16:19:55 +0000
treeherdermozilla-central@901dfde60183 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssicking
bugs730161
milestone14.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 730161 - Implement IDBRequest.error. r=sicking
dom/base/DOMError.cpp
dom/base/DOMError.h
dom/indexedDB/IDBRequest.cpp
dom/indexedDB/IDBRequest.h
dom/indexedDB/OpenDatabaseHelper.cpp
dom/indexedDB/nsIIDBRequest.idl
--- a/dom/base/DOMError.cpp
+++ b/dom/base/DOMError.cpp
@@ -3,32 +3,46 @@
 /* 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 "mozilla/Util.h"
 #include "nsDOMClassInfo.h"
+#include "nsDOMException.h"
 
 using mozilla::ArrayLength;
 using mozilla::dom::DOMError;
 
 namespace {
 
 struct NameMap
 {
   PRUint16 code;
   const char* name;
 };
 
 } // anonymous namespace
 
 // 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 nsnull;
+  }
+  return CreateWithName(NS_ConvertASCIItoUTF16(name));
+}
+
+// static
+already_AddRefed<nsIDOMDOMError>
 DOMError::CreateForDOMExceptionCode(PRUint16 aDOMExceptionCode)
 {
   // All of these codes (and yes, some are skipped) come from the spec.
   static const NameMap kNames[] = {
     {  1, "IndexSizeError" },
     {  3, "HierarchyRequestError" },
     {  4, "WrongDocumentError" },
     {  5, "InvalidCharacterError" },
--- a/dom/base/DOMError.h
+++ b/dom/base/DOMError.h
@@ -19,16 +19,19 @@ class DOMError : public nsIDOMDOMError
 {
   nsString mName;
 
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMDOMERROR
 
   static already_AddRefed<nsIDOMDOMError>
+  CreateForNSResult(nsresult rv);
+
+  static already_AddRefed<nsIDOMDOMError>
   CreateForDOMExceptionCode(PRUint16 aDOMExceptionCode);
 
   static already_AddRefed<nsIDOMDOMError>
   CreateWithName(const nsAString& aName)
   {
     nsCOMPtr<nsIDOMDOMError> error = new DOMError(aName);
     return error.forget();
   }
--- a/dom/indexedDB/IDBRequest.cpp
+++ b/dom/indexedDB/IDBRequest.cpp
@@ -51,22 +51,22 @@
 #include "nsPIDOMWindow.h"
 #include "nsStringGlue.h"
 #include "nsThreadUtils.h"
 #include "nsWrapperCacheInlines.h"
 
 #include "AsyncConnectionHelper.h"
 #include "IDBEvents.h"
 #include "IDBTransaction.h"
+#include "DOMError.h"
 
 USING_INDEXEDDB_NAMESPACE
 
 IDBRequest::IDBRequest()
 : mResultVal(JSVAL_VOID),
-  mErrorCode(0),
   mHaveResultOrErrorCode(false),
   mRooted(false)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 }
 
 IDBRequest::~IDBRequest()
 {
@@ -95,17 +95,17 @@ IDBRequest::Create(nsISupports* aSource,
 }
 
 void
 IDBRequest::Reset()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   mResultVal = JSVAL_VOID;
   mHaveResultOrErrorCode = false;
-  mErrorCode = 0;
+  mError = nsnull;
   UnrootResultVal();
 }
 
 nsresult
 IDBRequest::NotifyHelperCompleted(HelperBase* aHelper)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(!mHaveResultOrErrorCode, "Already called!");
@@ -119,30 +119,30 @@ IDBRequest::NotifyHelperCompleted(Helper
   }
 
   mHaveResultOrErrorCode = true;
 
   nsresult rv = aHelper->GetResultCode();
 
   // If the request failed then set the error code and return.
   if (NS_FAILED(rv)) {
-    mErrorCode = NS_ERROR_GET_CODE(rv);
+    mError = DOMError::CreateForNSResult(rv);
     return NS_OK;
   }
 
   // Otherwise we need to get the result from the helper.
   JSContext* cx;
   if (GetScriptOwner()) {
     nsIThreadJSContextStack* cxStack = nsContentUtils::ThreadJSContextStack();
     NS_ASSERTION(cxStack, "Failed to get thread context stack!");
 
     if (NS_FAILED(cxStack->GetSafeJSContext(&cx))) {
       NS_WARNING("Failed to get safe JSContext!");
       rv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
-      mErrorCode = NS_ERROR_GET_CODE(rv);
+      mError = DOMError::CreateForNSResult(rv);
       return rv;
     }
   }
   else {
     nsIScriptContext* sc = GetContextForEventHandlers(&rv);
     NS_ENSURE_STATE(sc);
     cx = sc->GetNativeContext();
     NS_ASSERTION(cx, "Failed to get a context!");
@@ -162,27 +162,36 @@ IDBRequest::NotifyHelperCompleted(Helper
     }
   }
   else {
     NS_WARNING("Failed to enter correct compartment!");
     rv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
   }
 
   if (NS_SUCCEEDED(rv)) {
-    mErrorCode = 0;
+    mError = nsnull;
   }
   else {
-    mErrorCode = NS_ERROR_GET_CODE(rv);
+    mError = DOMError::CreateForNSResult(rv);
     mResultVal = JSVAL_VOID;
   }
 
   return rv;
 }
 
 void
+IDBRequest::SetError(nsresult rv)
+{
+  NS_ASSERTION(NS_FAILED(rv), "Er, what?");
+  NS_ASSERTION(!mError, "Already have an error?");
+
+  mError = DOMError::CreateForNSResult(rv);
+}
+
+void
 IDBRequest::RootResultValInternal()
 {
   NS_HOLD_JS_OBJECTS(this, IDBRequest);
 }
 
 void
 IDBRequest::UnrootResultValInternal()
 {
@@ -234,26 +243,26 @@ IDBRequest::GetResult(jsval* aResult)
     return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
   }
 
   *aResult = mResultVal;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-IDBRequest::GetErrorCode(PRUint16* aErrorCode)
+IDBRequest::GetError(nsIDOMDOMError** aError)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (!mHaveResultOrErrorCode) {
     // XXX Need a real error code here.
     return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
   }
 
-  *aErrorCode = mErrorCode;
+  NS_IF_ADDREF(*aError = mError);
   return NS_OK;
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(IDBRequest)
 
 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.
--- a/dom/indexedDB/IDBRequest.h
+++ b/dom/indexedDB/IDBRequest.h
@@ -77,23 +77,17 @@ public:
   {
     return mSource;
   }
 
   void Reset();
 
   nsresult NotifyHelperCompleted(HelperBase* aHelper);
 
-  void SetError(nsresult rv)
-  {
-    NS_ASSERTION(NS_FAILED(rv), "Er, what?");
-    NS_ASSERTION(mErrorCode == NS_OK, "Already have an error?");
-
-    mErrorCode = rv;
-  }
+  void SetError(nsresult rv);
 
 protected:
   IDBRequest();
   ~IDBRequest();
 
   virtual void RootResultValInternal();
   virtual void UnrootResultValInternal();
 
@@ -116,17 +110,17 @@ protected:
   nsCOMPtr<nsISupports> mSource;
   nsRefPtr<IDBTransaction> mTransaction;
 
   NS_DECL_EVENT_HANDLER(success)
   NS_DECL_EVENT_HANDLER(error)
 
   jsval mResultVal;
 
-  PRUint16 mErrorCode;
+  nsCOMPtr<nsIDOMDOMError> mError;
   bool mHaveResultOrErrorCode;
   bool mRooted;
 };
 
 class IDBOpenDBRequest : public IDBRequest,
                          public nsIIDBOpenDBRequest
 {
 public:
--- a/dom/indexedDB/OpenDatabaseHelper.cpp
+++ b/dom/indexedDB/OpenDatabaseHelper.cpp
@@ -2196,21 +2196,21 @@ OpenDatabaseHelper::DispatchErrorEvent()
   nsRefPtr<nsDOMEvent> event =
     CreateGenericEvent(NS_LITERAL_STRING(ERROR_EVT_STR),
                        eDoesBubble, eCancelable);
   if (!event) {
     NS_ERROR("Failed to create event!");
     return;
   }
 
-  PRUint16 errorCode = 0;
+  nsCOMPtr<nsIDOMDOMError> error;
   DebugOnly<nsresult> rv =
-    mOpenDBRequest->GetErrorCode(&errorCode);
+    mOpenDBRequest->GetError(getter_AddRefs(error));
   NS_ASSERTION(NS_SUCCEEDED(rv), "This shouldn't be failing at this point!");
-  if (!errorCode) {
+  if (!error) {
     mOpenDBRequest->SetError(mResultCode);
   }
 
   bool dummy;
   mOpenDBRequest->DispatchEvent(event, &dummy);
 }
 
 void
--- a/dom/indexedDB/nsIIDBRequest.idl
+++ b/dom/indexedDB/nsIIDBRequest.idl
@@ -34,34 +34,35 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsISupports.idl"
+#include "nsIDOMDOMError.idl"
 
 interface nsIDOMEventListener;
 interface nsIIDBTransaction;
 
 /**
  * IDBReqeust interface.  See
  * http://dev.w3.org/2006/webapi/WebSimpleDB/#idl-def-IDBRequest for more
  * information.
  */
-[scriptable, builtinclass, uuid(fe30ca60-bb90-4d68-af2f-4735f9228a54)]
+[scriptable, builtinclass, uuid(4b9d901b-14a4-430c-b41b-5ecb238f4184)]
 interface nsIIDBRequest : nsISupports
 {
-  // "pending" or "done"
-  readonly attribute DOMString readyState;
+  readonly attribute jsval result;
+
+  readonly attribute nsIDOMDOMError error;
 
   readonly attribute nsISupports source;
 
   readonly attribute nsIIDBTransaction transaction;
 
-  readonly attribute jsval result;
-
-  readonly attribute unsigned short errorCode;
+  // "pending" or "done"
+  readonly attribute DOMString readyState;
 
   attribute nsIDOMEventListener onsuccess;
   attribute nsIDOMEventListener onerror;
 };