Bug 1544750 - Part 1: Refactor some IndexedDB code to use ErrorResult r=asuth
authorYaron Tausky <ytausky@mozilla.com>
Fri, 26 Apr 2019 16:53:59 +0000
changeset 530358 e8c59393c80952adfffd0be0de34c3ae7e48e36a
parent 530357 d9a0cc432b2e898d3fc74a2183c931018237c668
child 530359 2eda2b8941d4640fe8c4e2de8629f8b629de0a9c
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersasuth
bugs1544750
milestone68.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 1544750 - Part 1: Refactor some IndexedDB code to use ErrorResult r=asuth This is mostly laying the groundwork for further refactoring. Differential Revision: https://phabricator.services.mozilla.com/D27666
dom/indexedDB/ActorsParent.cpp
dom/indexedDB/IDBCursor.cpp
dom/indexedDB/IDBFactory.cpp
dom/indexedDB/IDBIndex.cpp
dom/indexedDB/IDBKeyRange.cpp
dom/indexedDB/IDBKeyRange.h
dom/indexedDB/IDBObjectStore.cpp
dom/indexedDB/IDBObjectStore.h
dom/indexedDB/Key.cpp
dom/indexedDB/Key.h
--- a/dom/indexedDB/ActorsParent.cpp
+++ b/dom/indexedDB/ActorsParent.cpp
@@ -22979,21 +22979,23 @@ CreateIndexOp::UpdateIndexDataValuesFunc
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   const IndexMetadata& metadata = mOp->mMetadata;
   const int64_t& objectStoreId = mOp->mObjectStoreId;
 
   AutoTArray<IndexUpdateInfo, 32> updateInfos;
-  rv = IDBObjectStore::DeserializeIndexValueToUpdateInfos(
+  ErrorResult errorResult;
+  IDBObjectStore::DeserializeIndexValueToUpdateInfos(
       metadata.id(), metadata.keyPath(), metadata.unique(),
-      metadata.multiEntry(), metadata.locale(), cloneInfo, updateInfos);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
+      metadata.multiEntry(), metadata.locale(), cloneInfo, updateInfos,
+      errorResult);
+  if (NS_WARN_IF(errorResult.Failed())) {
+    return errorResult.StealNSResult();
   }
 
   if (updateInfos.IsEmpty()) {
     // XXX See if we can do this without copying...
 
     nsCOMPtr<nsIVariant> unmodifiedValue;
 
     // No changes needed, just return the original value.
--- a/dom/indexedDB/IDBCursor.cpp
+++ b/dom/indexedDB/IDBCursor.cpp
@@ -376,17 +376,17 @@ void IDBCursor::Continue(JSContext* aCx,
   }
 
   if (IsSourceDeleted() || !mHaveValue || mContinueCalled) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
     return;
   }
 
   Key key;
-  aRv = key.SetFromJSVal(aCx, aKey);
+  key.SetFromJSVal(aCx, aKey, aRv);
   if (aRv.Failed()) {
     return;
   }
 
   if (IsLocaleAware() && !key.IsUnset()) {
     Key tmp;
     aRv = key.ToLocaleBasedKey(tmp, mSourceIndex->Locale());
     if (aRv.Failed()) {
@@ -474,17 +474,17 @@ void IDBCursor::ContinuePrimaryKey(JSCon
   }
 
   if (!mHaveValue || mContinueCalled) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
     return;
   }
 
   Key key;
-  aRv = key.SetFromJSVal(aCx, aKey);
+  key.SetFromJSVal(aCx, aKey, aRv);
   if (aRv.Failed()) {
     return;
   }
 
   if (IsLocaleAware() && !key.IsUnset()) {
     Key tmp;
     aRv = key.ToLocaleBasedKey(tmp, mSourceIndex->Locale());
     if (aRv.Failed()) {
@@ -496,17 +496,17 @@ void IDBCursor::ContinuePrimaryKey(JSCon
   const Key& sortKey = IsLocaleAware() ? mSortKey : mKey;
 
   if (key.IsUnset()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_DATA_ERR);
     return;
   }
 
   Key primaryKey;
-  aRv = primaryKey.SetFromJSVal(aCx, aPrimaryKey);
+  primaryKey.SetFromJSVal(aCx, aPrimaryKey, aRv);
   if (aRv.Failed()) {
     return;
   }
 
   if (primaryKey.IsUnset()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_DATA_ERR);
     return;
   }
--- a/dom/indexedDB/IDBFactory.cpp
+++ b/dom/indexedDB/IDBFactory.cpp
@@ -496,25 +496,23 @@ already_AddRefed<IDBOpenDBRequest> IDBFa
                       /* aPrincipal */ nullptr, aName, Optional<uint64_t>(),
                       aOptions.mStorage,
                       /* aDeleting */ true, aCallerType, aRv);
 }
 
 int16_t IDBFactory::Cmp(JSContext* aCx, JS::Handle<JS::Value> aFirst,
                         JS::Handle<JS::Value> aSecond, ErrorResult& aRv) {
   Key first, second;
-  nsresult rv = first.SetFromJSVal(aCx, aFirst);
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
+  first.SetFromJSVal(aCx, aFirst, aRv);
+  if (aRv.Failed()) {
     return 0;
   }
 
-  rv = second.SetFromJSVal(aCx, aSecond);
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
+  second.SetFromJSVal(aCx, aSecond, aRv);
+  if (aRv.Failed()) {
     return 0;
   }
 
   if (first.IsUnset() || second.IsUnset()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_DATA_ERR);
     return 0;
   }
 
--- a/dom/indexedDB/IDBIndex.cpp
+++ b/dom/indexedDB/IDBIndex.cpp
@@ -282,17 +282,17 @@ already_AddRefed<IDBRequest> IDBIndex::G
 
   IDBTransaction* transaction = mObjectStore->Transaction();
   if (!transaction->IsOpen()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
     return nullptr;
   }
 
   RefPtr<IDBKeyRange> keyRange;
-  aRv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
+  IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange), aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
   if (!keyRange) {
     // Must specify a key or keyRange for get() and getKey().
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_KEY_ERR);
     return nullptr;
@@ -355,17 +355,17 @@ already_AddRefed<IDBRequest> IDBIndex::G
 
   IDBTransaction* transaction = mObjectStore->Transaction();
   if (!transaction->IsOpen()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
     return nullptr;
   }
 
   RefPtr<IDBKeyRange> keyRange;
-  aRv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
+  IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange), aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
   const int64_t objectStoreId = mObjectStore->Id();
   const int64_t indexId = Id();
 
   Maybe<SerializedKeyRange> optionalKeyRange;
@@ -431,17 +431,17 @@ already_AddRefed<IDBRequest> IDBIndex::O
 
   IDBTransaction* transaction = mObjectStore->Transaction();
   if (!transaction->IsOpen()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
     return nullptr;
   }
 
   RefPtr<IDBKeyRange> keyRange;
-  aRv = IDBKeyRange::FromJSVal(aCx, aRange, getter_AddRefs(keyRange));
+  IDBKeyRange::FromJSVal(aCx, aRange, getter_AddRefs(keyRange), aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
   int64_t objectStoreId = mObjectStore->Id();
   int64_t indexId = Id();
 
   Maybe<SerializedKeyRange> optionalKeyRange;
@@ -524,17 +524,17 @@ already_AddRefed<IDBRequest> IDBIndex::C
 
   IDBTransaction* transaction = mObjectStore->Transaction();
   if (!transaction->IsOpen()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
     return nullptr;
   }
 
   RefPtr<IDBKeyRange> keyRange;
-  aRv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
+  IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange), aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
   IndexCountParams params;
   params.objectStoreId() = mObjectStore->Id();
   params.indexId() = Id();
 
--- a/dom/indexedDB/IDBKeyRange.cpp
+++ b/dom/indexedDB/IDBKeyRange.cpp
@@ -14,29 +14,26 @@
 
 namespace mozilla {
 namespace dom {
 
 using namespace mozilla::dom::indexedDB;
 
 namespace {
 
-nsresult GetKeyFromJSVal(JSContext* aCx, JS::Handle<JS::Value> aVal,
-                         Key& aKey) {
-  nsresult rv = aKey.SetFromJSVal(aCx, aVal);
-  if (NS_FAILED(rv)) {
-    MOZ_ASSERT(NS_ERROR_GET_MODULE(rv) == NS_ERROR_MODULE_DOM_INDEXEDDB);
-    return rv;
+void GetKeyFromJSVal(JSContext* aCx, JS::Handle<JS::Value> aVal, Key& aKey,
+                     ErrorResult& aRv) {
+  aKey.SetFromJSVal(aCx, aVal, aRv);
+  if (aRv.Failed()) {
+    return;
   }
 
   if (aKey.IsUnset()) {
-    return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_DATA_ERR);
   }
-
-  return NS_OK;
 }
 
 }  // namespace
 
 IDBKeyRange::IDBKeyRange(nsISupports* aGlobal, bool aLowerOpen, bool aUpperOpen,
                          bool aIsOnly)
     : mGlobal(aGlobal),
       mCachedLowerVal(JS::UndefinedValue()),
@@ -57,46 +54,43 @@ IDBLocaleAwareKeyRange::IDBLocaleAwareKe
                                                bool aIsOnly)
     : IDBKeyRange(aGlobal, aLowerOpen, aUpperOpen, aIsOnly) {
   AssertIsOnOwningThread();
 }
 
 IDBLocaleAwareKeyRange::~IDBLocaleAwareKeyRange() { DropJSObjects(); }
 
 // static
-nsresult IDBKeyRange::FromJSVal(JSContext* aCx, JS::Handle<JS::Value> aVal,
-                                IDBKeyRange** aKeyRange) {
+void IDBKeyRange::FromJSVal(JSContext* aCx, JS::Handle<JS::Value> aVal,
+                            IDBKeyRange** aKeyRange, ErrorResult& aRv) {
   MOZ_ASSERT_IF(!aCx, aVal.isUndefined());
 
   RefPtr<IDBKeyRange> keyRange;
 
   if (aVal.isNullOrUndefined()) {
     // undefined and null returns no IDBKeyRange.
     keyRange.forget(aKeyRange);
-    return NS_OK;
+    return;
   }
 
   JS::Rooted<JSObject*> obj(aCx, aVal.isObject() ? &aVal.toObject() : nullptr);
 
   // Unwrap an IDBKeyRange object if possible.
   if (obj && NS_SUCCEEDED(UNWRAP_OBJECT(IDBKeyRange, obj, keyRange))) {
     MOZ_ASSERT(keyRange);
     keyRange.forget(aKeyRange);
-    return NS_OK;
+    return;
   }
 
   // A valid key returns an 'only' IDBKeyRange.
   keyRange = new IDBKeyRange(nullptr, false, false, true);
-  nsresult rv = GetKeyFromJSVal(aCx, aVal, keyRange->Lower());
-  if (NS_FAILED(rv)) {
-    return rv;
+  GetKeyFromJSVal(aCx, aVal, keyRange->Lower(), aRv);
+  if (!aRv.Failed()) {
+    keyRange.forget(aKeyRange);
   }
-
-  keyRange.forget(aKeyRange);
-  return NS_OK;
 }
 
 // static
 already_AddRefed<IDBKeyRange> IDBKeyRange::FromSerialized(
     const SerializedKeyRange& aKeyRange) {
   RefPtr<IDBKeyRange> keyRange =
       new IDBKeyRange(nullptr, aKeyRange.lowerOpen(), aKeyRange.upperOpen(),
                       aKeyRange.isOnly());
@@ -271,17 +265,17 @@ void IDBKeyRange::GetUpper(JSContext* aC
   }
 
   aResult.set(mCachedUpperVal);
 }
 
 bool IDBKeyRange::Includes(JSContext* aCx, JS::Handle<JS::Value> aValue,
                            ErrorResult& aRv) const {
   Key key;
-  aRv = GetKeyFromJSVal(aCx, aValue, key);
+  GetKeyFromJSVal(aCx, aValue, key, aRv);
   if (aRv.Failed()) {
     return false;
   }
 
   MOZ_ASSERT(!(Lower().IsUnset() && Upper().IsUnset()));
   MOZ_ASSERT_IF(IsOnly(), !Lower().IsUnset() && !LowerOpen() &&
                               Lower() == Upper() && LowerOpen() == UpperOpen());
 
@@ -319,47 +313,47 @@ bool IDBKeyRange::Includes(JSContext* aC
 
 // static
 already_AddRefed<IDBKeyRange> IDBKeyRange::Only(const GlobalObject& aGlobal,
                                                 JS::Handle<JS::Value> aValue,
                                                 ErrorResult& aRv) {
   RefPtr<IDBKeyRange> keyRange =
       new IDBKeyRange(aGlobal.GetAsSupports(), false, false, true);
 
-  aRv = GetKeyFromJSVal(aGlobal.Context(), aValue, keyRange->Lower());
+  GetKeyFromJSVal(aGlobal.Context(), aValue, keyRange->Lower(), aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
   return keyRange.forget();
 }
 
 // static
 already_AddRefed<IDBKeyRange> IDBKeyRange::LowerBound(
     const GlobalObject& aGlobal, JS::Handle<JS::Value> aValue, bool aOpen,
     ErrorResult& aRv) {
   RefPtr<IDBKeyRange> keyRange =
       new IDBKeyRange(aGlobal.GetAsSupports(), aOpen, true, false);
 
-  aRv = GetKeyFromJSVal(aGlobal.Context(), aValue, keyRange->Lower());
+  GetKeyFromJSVal(aGlobal.Context(), aValue, keyRange->Lower(), aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
   return keyRange.forget();
 }
 
 // static
 already_AddRefed<IDBKeyRange> IDBKeyRange::UpperBound(
     const GlobalObject& aGlobal, JS::Handle<JS::Value> aValue, bool aOpen,
     ErrorResult& aRv) {
   RefPtr<IDBKeyRange> keyRange =
       new IDBKeyRange(aGlobal.GetAsSupports(), true, aOpen, false);
 
-  aRv = GetKeyFromJSVal(aGlobal.Context(), aValue, keyRange->Upper());
+  GetKeyFromJSVal(aGlobal.Context(), aValue, keyRange->Upper(), aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
   return keyRange.forget();
 }
 
 // static
@@ -367,22 +361,22 @@ already_AddRefed<IDBKeyRange> IDBKeyRang
                                                  JS::Handle<JS::Value> aLower,
                                                  JS::Handle<JS::Value> aUpper,
                                                  bool aLowerOpen,
                                                  bool aUpperOpen,
                                                  ErrorResult& aRv) {
   RefPtr<IDBKeyRange> keyRange =
       new IDBKeyRange(aGlobal.GetAsSupports(), aLowerOpen, aUpperOpen, false);
 
-  aRv = GetKeyFromJSVal(aGlobal.Context(), aLower, keyRange->Lower());
+  GetKeyFromJSVal(aGlobal.Context(), aLower, keyRange->Lower(), aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
-  aRv = GetKeyFromJSVal(aGlobal.Context(), aUpper, keyRange->Upper());
+  GetKeyFromJSVal(aGlobal.Context(), aUpper, keyRange->Upper(), aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
   if (keyRange->Lower() > keyRange->Upper() ||
       (keyRange->Lower() == keyRange->Upper() && (aLowerOpen || aUpperOpen))) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_DATA_ERR);
     return nullptr;
@@ -394,22 +388,22 @@ already_AddRefed<IDBKeyRange> IDBKeyRang
 // static
 already_AddRefed<IDBLocaleAwareKeyRange> IDBLocaleAwareKeyRange::Bound(
     const GlobalObject& aGlobal, JS::Handle<JS::Value> aLower,
     JS::Handle<JS::Value> aUpper, bool aLowerOpen, bool aUpperOpen,
     ErrorResult& aRv) {
   RefPtr<IDBLocaleAwareKeyRange> keyRange = new IDBLocaleAwareKeyRange(
       aGlobal.GetAsSupports(), aLowerOpen, aUpperOpen, false);
 
-  aRv = GetKeyFromJSVal(aGlobal.Context(), aLower, keyRange->Lower());
+  GetKeyFromJSVal(aGlobal.Context(), aLower, keyRange->Lower(), aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
-  aRv = GetKeyFromJSVal(aGlobal.Context(), aUpper, keyRange->Upper());
+  GetKeyFromJSVal(aGlobal.Context(), aUpper, keyRange->Upper(), aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
   if (keyRange->Lower() == keyRange->Upper() && (aLowerOpen || aUpperOpen)) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_DATA_ERR);
     return nullptr;
   }
--- a/dom/indexedDB/IDBKeyRange.h
+++ b/dom/indexedDB/IDBKeyRange.h
@@ -46,18 +46,18 @@ class IDBKeyRange : public nsISupports {
   bool mHaveCachedUpperVal : 1;
   bool mRooted : 1;
 
  public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBKeyRange)
 
   // aCx is allowed to be null, but only if aVal.isUndefined().
-  static nsresult FromJSVal(JSContext* aCx, JS::Handle<JS::Value> aVal,
-                            IDBKeyRange** aKeyRange);
+  static void FromJSVal(JSContext* aCx, JS::Handle<JS::Value> aVal,
+                        IDBKeyRange** aKeyRange, ErrorResult& aRv);
 
   static already_AddRefed<IDBKeyRange> FromSerialized(
       const indexedDB::SerializedKeyRange& aKeyRange);
 
   static already_AddRefed<IDBKeyRange> Only(const GlobalObject& aGlobal,
                                             JS::Handle<JS::Value> aValue,
                                             ErrorResult& aRv);
 
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -918,110 +918,117 @@ already_AddRefed<IDBObjectStore> IDBObje
   aTransaction->AssertIsOnOwningThread();
 
   RefPtr<IDBObjectStore> objectStore = new IDBObjectStore(aTransaction, &aSpec);
 
   return objectStore.forget();
 }
 
 // static
-nsresult IDBObjectStore::AppendIndexUpdateInfo(
+void IDBObjectStore::AppendIndexUpdateInfo(
     int64_t aIndexID, const KeyPath& aKeyPath, bool aUnique, bool aMultiEntry,
     const nsCString& aLocale, JSContext* aCx, JS::Handle<JS::Value> aVal,
-    nsTArray<IndexUpdateInfo>& aUpdateInfoArray) {
-  nsresult rv;
-
+    nsTArray<IndexUpdateInfo>& aUpdateInfoArray, ErrorResult& aRv) {
   const bool localeAware = !aLocale.IsEmpty();
 
   if (!aMultiEntry) {
     Key key;
-    rv = aKeyPath.ExtractKey(aCx, aVal, key);
+    aRv = aKeyPath.ExtractKey(aCx, aVal, key);
 
     // If an index's keyPath doesn't match an object, we ignore that object.
-    if (rv == NS_ERROR_DOM_INDEXEDDB_DATA_ERR || key.IsUnset()) {
-      return NS_OK;
+    if (aRv.ErrorCodeIs(NS_ERROR_DOM_INDEXEDDB_DATA_ERR) || key.IsUnset()) {
+      aRv.SuppressException();
+      return;
     }
 
-    if (NS_FAILED(rv)) {
-      return rv;
+    if (aRv.Failed()) {
+      return;
     }
 
     IndexUpdateInfo* updateInfo = aUpdateInfoArray.AppendElement();
     updateInfo->indexId() = aIndexID;
     updateInfo->value() = key;
     if (localeAware) {
-      rv = key.ToLocaleBasedKey(updateInfo->localizedValue(), aLocale);
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+      aRv = key.ToLocaleBasedKey(updateInfo->localizedValue(), aLocale);
+      if (NS_WARN_IF(aRv.Failed())) {
+        aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+        return;
       }
     }
 
-    return NS_OK;
+    return;
   }
 
   JS::Rooted<JS::Value> val(aCx);
   if (NS_FAILED(aKeyPath.ExtractKeyAsJSVal(aCx, aVal, val.address()))) {
-    return NS_OK;
+    return;
   }
 
   bool isArray;
   if (!JS_IsArrayObject(aCx, val, &isArray)) {
     IDB_REPORT_INTERNAL_ERR();
-    return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    return;
   }
   if (isArray) {
     JS::Rooted<JSObject*> array(aCx, &val.toObject());
     uint32_t arrayLength;
     if (NS_WARN_IF(!JS_GetArrayLength(aCx, array, &arrayLength))) {
       IDB_REPORT_INTERNAL_ERR();
-      return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+      aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+      return;
     }
 
     for (uint32_t arrayIndex = 0; arrayIndex < arrayLength; arrayIndex++) {
       JS::Rooted<JS::Value> arrayItem(aCx);
       if (NS_WARN_IF(!JS_GetElement(aCx, array, arrayIndex, &arrayItem))) {
         IDB_REPORT_INTERNAL_ERR();
-        return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+        aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+        return;
       }
 
       Key value;
-      if (NS_FAILED(value.SetFromJSVal(aCx, arrayItem)) || value.IsUnset()) {
+      value.SetFromJSVal(aCx, arrayItem, aRv);
+      if (aRv.Failed() || value.IsUnset()) {
         // Not a value we can do anything with, ignore it.
+        aRv.SuppressException();
         continue;
       }
 
       IndexUpdateInfo* updateInfo = aUpdateInfoArray.AppendElement();
       updateInfo->indexId() = aIndexID;
       updateInfo->value() = value;
       if (localeAware) {
-        rv = value.ToLocaleBasedKey(updateInfo->localizedValue(), aLocale);
-        if (NS_WARN_IF(NS_FAILED(rv))) {
-          return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+        aRv = value.ToLocaleBasedKey(updateInfo->localizedValue(), aLocale);
+        if (NS_WARN_IF(aRv.Failed())) {
+          aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+          return;
         }
       }
     }
   } else {
     Key value;
-    if (NS_FAILED(value.SetFromJSVal(aCx, val)) || value.IsUnset()) {
+    value.SetFromJSVal(aCx, val, aRv);
+    if (aRv.Failed() || value.IsUnset()) {
       // Not a value we can do anything with, ignore it.
-      return NS_OK;
+      aRv.SuppressException();
+      return;
     }
 
     IndexUpdateInfo* updateInfo = aUpdateInfoArray.AppendElement();
     updateInfo->indexId() = aIndexID;
     updateInfo->value() = value;
     if (localeAware) {
-      rv = value.ToLocaleBasedKey(updateInfo->localizedValue(), aLocale);
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+      aRv = value.ToLocaleBasedKey(updateInfo->localizedValue(), aLocale);
+      if (NS_WARN_IF(aRv.Failed())) {
+        aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+        return;
       }
     }
   }
-
-  return NS_OK;
 }
 
 // static
 void IDBObjectStore::ClearCloneReadInfo(StructuredCloneReadInfo& aReadInfo) {
   // This is kind of tricky, we only want to release stuff on the main thread,
   // but we can end up being called on other threads if we have already been
   // cleared on the main thread.
   if (!aReadInfo.mFiles.Length()) {
@@ -1129,45 +1136,48 @@ class DeserializeIndexValueHelper final 
         mKeyPath(aKeyPath),
         mUnique(aUnique),
         mMultiEntry(aMultiEntry),
         mLocale(aLocale),
         mCloneReadInfo(aCloneReadInfo),
         mUpdateInfoArray(aUpdateInfoArray),
         mStatus(NS_ERROR_FAILURE) {}
 
-  nsresult DispatchAndWait() {
+  void DispatchAndWait(ErrorResult& aRv) {
     // We don't need to go to the main-thread and use the sandbox. Let's create
     // the updateInfo data here.
     if (!mCloneReadInfo.mData.Size()) {
       AutoJSAPI jsapi;
       jsapi.Init();
 
       JS::Rooted<JS::Value> value(jsapi.cx());
       value.setUndefined();
 
-      return IDBObjectStore::AppendIndexUpdateInfo(
-          mIndexID, mKeyPath, mUnique, mMultiEntry, mLocale, jsapi.cx(), value,
-          mUpdateInfoArray);
+      IDBObjectStore::AppendIndexUpdateInfo(mIndexID, mKeyPath, mUnique,
+                                            mMultiEntry, mLocale, jsapi.cx(),
+                                            value, mUpdateInfoArray, aRv);
+      return;
     }
 
     // The operation will continue on the main-thread.
 
     MOZ_ASSERT(!(mCloneReadInfo.mData.Size() % sizeof(uint64_t)));
 
     MonitorAutoLock lock(mMonitor);
 
     RefPtr<Runnable> self = this;
-    nsresult rv = SystemGroup::Dispatch(TaskCategory::Other, self.forget());
+    const nsresult rv =
+        SystemGroup::Dispatch(TaskCategory::Other, self.forget());
     if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
+      aRv.Throw(rv);
+      return;
     }
 
     lock.Wait();
-    return mStatus;
+    aRv = mStatus;
   }
 
   NS_IMETHOD
   Run() override {
     MOZ_ASSERT(NS_IsMainThread());
 
     AutoJSAPI jsapi;
     jsapi.Init();
@@ -1177,27 +1187,28 @@ class DeserializeIndexValueHelper final 
     if (NS_WARN_IF(!global)) {
       OperationCompleted(NS_ERROR_FAILURE);
       return NS_OK;
     }
 
     JSAutoRealm ar(cx, global);
 
     JS::Rooted<JS::Value> value(cx);
-    nsresult rv = DeserializeIndexValue(cx, &value);
+    const nsresult rv = DeserializeIndexValue(cx, &value);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       OperationCompleted(rv);
       return NS_OK;
     }
 
-    rv = IDBObjectStore::AppendIndexUpdateInfo(mIndexID, mKeyPath, mUnique,
-                                               mMultiEntry, mLocale, cx, value,
-                                               mUpdateInfoArray);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      OperationCompleted(rv);
+    ErrorResult errorResult;
+    IDBObjectStore::AppendIndexUpdateInfo(mIndexID, mKeyPath, mUnique,
+                                          mMultiEntry, mLocale, cx, value,
+                                          mUpdateInfoArray, errorResult);
+    if (NS_WARN_IF(errorResult.Failed())) {
+      OperationCompleted(errorResult.StealNSResult());
       return NS_OK;
     }
 
     OperationCompleted(NS_OK);
     return NS_OK;
   }
 
  private:
@@ -1353,26 +1364,26 @@ class DeserializeUpgradeValueHelper fina
   Monitor mMonitor;
   StructuredCloneReadInfo& mCloneReadInfo;
   nsresult mStatus;
 };
 
 }  // namespace
 
 // static
-nsresult IDBObjectStore::DeserializeIndexValueToUpdateInfos(
+void IDBObjectStore::DeserializeIndexValueToUpdateInfos(
     int64_t aIndexID, const KeyPath& aKeyPath, bool aUnique, bool aMultiEntry,
     const nsCString& aLocale, StructuredCloneReadInfo& aCloneReadInfo,
-    nsTArray<IndexUpdateInfo>& aUpdateInfoArray) {
+    nsTArray<IndexUpdateInfo>& aUpdateInfoArray, ErrorResult& aRv) {
   MOZ_ASSERT(!NS_IsMainThread());
 
   RefPtr<DeserializeIndexValueHelper> helper = new DeserializeIndexValueHelper(
       aIndexID, aKeyPath, aUnique, aMultiEntry, aLocale, aCloneReadInfo,
       aUpdateInfoArray);
-  return helper->DispatchAndWait();
+  helper->DispatchAndWait(aRv);
 }
 
 // static
 nsresult IDBObjectStore::DeserializeUpgradeValueToFileIds(
     StructuredCloneReadInfo& aCloneReadInfo, nsAString& aFileIds) {
   MOZ_ASSERT(!NS_IsMainThread());
 
   RefPtr<DeserializeUpgradeValueHelper> helper =
@@ -1384,96 +1395,99 @@ nsresult IDBObjectStore::DeserializeUpgr
 
 void IDBObjectStore::AssertIsOnOwningThread() const {
   MOZ_ASSERT(mTransaction);
   mTransaction->AssertIsOnOwningThread();
 }
 
 #endif  // DEBUG
 
-nsresult IDBObjectStore::GetAddInfo(
-    JSContext* aCx, ValueWrapper& aValueWrapper, JS::Handle<JS::Value> aKeyVal,
-    StructuredCloneWriteInfo& aCloneWriteInfo, Key& aKey,
-    nsTArray<IndexUpdateInfo>& aUpdateInfoArray) {
+void IDBObjectStore::GetAddInfo(JSContext* aCx, ValueWrapper& aValueWrapper,
+                                JS::Handle<JS::Value> aKeyVal,
+                                StructuredCloneWriteInfo& aCloneWriteInfo,
+                                Key& aKey,
+                                nsTArray<IndexUpdateInfo>& aUpdateInfoArray,
+                                ErrorResult& aRv) {
   // Return DATA_ERR if a key was passed in and this objectStore uses inline
   // keys.
   if (!aKeyVal.isUndefined() && HasValidKeyPath()) {
-    return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_DATA_ERR);
+    return;
   }
 
   bool isAutoIncrement = AutoIncrement();
 
-  nsresult rv;
-
   if (!HasValidKeyPath()) {
     // Out-of-line keys must be passed in.
-    rv = aKey.SetFromJSVal(aCx, aKeyVal);
-    if (NS_FAILED(rv)) {
-      return rv;
+    aKey.SetFromJSVal(aCx, aKeyVal, aRv);
+    if (aRv.Failed()) {
+      return;
     }
   } else if (!isAutoIncrement) {
     if (!aValueWrapper.Clone(aCx)) {
-      return NS_ERROR_DOM_DATA_CLONE_ERR;
+      aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
+      return;
     }
 
-    rv = GetKeyPath().ExtractKey(aCx, aValueWrapper.Value(), aKey);
-    if (NS_FAILED(rv)) {
-      return rv;
+    aRv = GetKeyPath().ExtractKey(aCx, aValueWrapper.Value(), aKey);
+    if (aRv.Failed()) {
+      return;
     }
   }
 
   // Return DATA_ERR if no key was specified this isn't an autoIncrement
   // objectStore.
   if (aKey.IsUnset() && !isAutoIncrement) {
-    return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_DATA_ERR);
+    return;
   }
 
   // Figure out indexes and the index values to update here.
 
   if (mSpec->indexes().Length() && !aValueWrapper.Clone(aCx)) {
-    return NS_ERROR_DOM_DATA_CLONE_ERR;
+    aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
+    return;
   }
 
   {
     const nsTArray<IndexMetadata>& indexes = mSpec->indexes();
     uint32_t idxCount = indexes.Length();
 
     aUpdateInfoArray.SetCapacity(idxCount);  // Pretty good estimate
 
     for (uint32_t idxIndex = 0; idxIndex < idxCount; idxIndex++) {
       const IndexMetadata& metadata = indexes[idxIndex];
 
-      rv = AppendIndexUpdateInfo(metadata.id(), metadata.keyPath(),
-                                 metadata.unique(), metadata.multiEntry(),
-                                 metadata.locale(), aCx, aValueWrapper.Value(),
-                                 aUpdateInfoArray);
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return rv;
+      AppendIndexUpdateInfo(metadata.id(), metadata.keyPath(),
+                            metadata.unique(), metadata.multiEntry(),
+                            metadata.locale(), aCx, aValueWrapper.Value(),
+                            aUpdateInfoArray, aRv);
+      if (NS_WARN_IF(aRv.Failed())) {
+        return;
       }
     }
   }
 
   if (isAutoIncrement && HasValidKeyPath()) {
     if (!aValueWrapper.Clone(aCx)) {
-      return NS_ERROR_DOM_DATA_CLONE_ERR;
+      aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
+      return;
     }
 
     GetAddInfoClosure data(aCloneWriteInfo, aValueWrapper.Value());
 
     MOZ_ASSERT(aKey.IsUnset());
 
-    rv = GetKeyPath().ExtractOrCreateKey(aCx, aValueWrapper.Value(), aKey,
-                                         &GetAddInfoCallback, &data);
+    aRv = GetKeyPath().ExtractOrCreateKey(aCx, aValueWrapper.Value(), aKey,
+                                          &GetAddInfoCallback, &data);
   } else {
     GetAddInfoClosure data(aCloneWriteInfo, aValueWrapper.Value());
 
-    rv = GetAddInfoCallback(aCx, &data);
+    aRv = GetAddInfoCallback(aCx, &data);
   }
-
-  return rv;
 }
 
 already_AddRefed<IDBRequest> IDBObjectStore::AddOrPut(
     JSContext* aCx, ValueWrapper& aValueWrapper, JS::Handle<JS::Value> aKey,
     bool aOverwrite, bool aFromCursor, ErrorResult& aRv) {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aCx);
   MOZ_ASSERT_IF(aFromCursor, aOverwrite);
@@ -1492,17 +1506,17 @@ already_AddRefed<IDBRequest> IDBObjectSt
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR);
     return nullptr;
   }
 
   Key key;
   StructuredCloneWriteInfo cloneWriteInfo(mTransaction->Database());
   nsTArray<IndexUpdateInfo> updateInfo;
 
-  aRv = GetAddInfo(aCx, aValueWrapper, aKey, cloneWriteInfo, key, updateInfo);
+  GetAddInfo(aCx, aValueWrapper, aKey, cloneWriteInfo, key, updateInfo, aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
   if (!mTransaction->IsOpen()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
     return nullptr;
   }
@@ -1677,17 +1691,17 @@ already_AddRefed<IDBRequest> IDBObjectSt
   }
 
   if (!mTransaction->IsOpen()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
     return nullptr;
   }
 
   RefPtr<IDBKeyRange> keyRange;
-  aRv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
+  IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange), aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
   const int64_t id = Id();
 
   Maybe<SerializedKeyRange> optionalKeyRange;
   if (keyRange) {
@@ -1924,17 +1938,17 @@ already_AddRefed<IDBRequest> IDBObjectSt
   }
 
   if (!mTransaction->IsOpen()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
     return nullptr;
   }
 
   RefPtr<IDBKeyRange> keyRange;
-  aRv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
+  IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange), aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
   if (!keyRange) {
     // Must specify a key or keyRange for get().
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_KEY_ERR);
     return nullptr;
@@ -1986,17 +2000,17 @@ already_AddRefed<IDBRequest> IDBObjectSt
   }
 
   if (!mTransaction->IsWriteAllowed()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR);
     return nullptr;
   }
 
   RefPtr<IDBKeyRange> keyRange;
-  aRv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
+  IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange), aRv);
   if (NS_WARN_IF((aRv.Failed()))) {
     return nullptr;
   }
 
   if (!keyRange) {
     // Must specify a key or keyRange for delete().
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_KEY_ERR);
     return nullptr;
@@ -2213,17 +2227,17 @@ already_AddRefed<IDBRequest> IDBObjectSt
   }
 
   if (!mTransaction->IsOpen()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
     return nullptr;
   }
 
   RefPtr<IDBKeyRange> keyRange;
-  aRv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
+  IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange), aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
   ObjectStoreCountParams params;
   params.objectStoreId() = Id();
 
   if (keyRange) {
@@ -2262,17 +2276,17 @@ already_AddRefed<IDBRequest> IDBObjectSt
   }
 
   if (!mTransaction->IsOpen()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
     return nullptr;
   }
 
   RefPtr<IDBKeyRange> keyRange;
-  aRv = IDBKeyRange::FromJSVal(aCx, aRange, getter_AddRefs(keyRange));
+  IDBKeyRange::FromJSVal(aCx, aRange, getter_AddRefs(keyRange), aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
   int64_t objectStoreId = Id();
 
   Maybe<SerializedKeyRange> optionalKeyRange;
 
--- a/dom/indexedDB/IDBObjectStore.h
+++ b/dom/indexedDB/IDBObjectStore.h
@@ -89,25 +89,27 @@ class IDBObjectStore final : public nsIS
     const JS::Rooted<JS::Value>& Value() const { return mValue; }
 
     bool Clone(JSContext* aCx);
   };
 
   static already_AddRefed<IDBObjectStore> Create(IDBTransaction* aTransaction,
                                                  const ObjectStoreSpec& aSpec);
 
-  static nsresult AppendIndexUpdateInfo(
-      int64_t aIndexID, const KeyPath& aKeyPath, bool aUnique, bool aMultiEntry,
-      const nsCString& aLocale, JSContext* aCx, JS::Handle<JS::Value> aObject,
-      nsTArray<IndexUpdateInfo>& aUpdateInfoArray);
+  static void AppendIndexUpdateInfo(int64_t aIndexID, const KeyPath& aKeyPath,
+                                    bool aUnique, bool aMultiEntry,
+                                    const nsCString& aLocale, JSContext* aCx,
+                                    JS::Handle<JS::Value> aVal,
+                                    nsTArray<IndexUpdateInfo>& aUpdateInfoArray,
+                                    ErrorResult& aRv);
 
-  static nsresult DeserializeIndexValueToUpdateInfos(
+  static void DeserializeIndexValueToUpdateInfos(
       int64_t aIndexID, const KeyPath& aKeyPath, bool aUnique, bool aMultiEntry,
-      const nsCString& aLocale, StructuredCloneReadInfo& aCloneInfo,
-      nsTArray<IndexUpdateInfo>& aUpdateInfoArray);
+      const nsCString& aLocale, StructuredCloneReadInfo& aCloneReadInfo,
+      nsTArray<IndexUpdateInfo>& aUpdateInfoArray, ErrorResult& aRv);
 
   static void ClearCloneReadInfo(StructuredCloneReadInfo& aReadInfo);
 
   static bool DeserializeValue(JSContext* aCx,
                                StructuredCloneReadInfo& aCloneReadInfo,
                                JS::MutableHandle<JS::Value> aValue);
 
   static nsresult DeserializeUpgradeValueToFileIds(
@@ -282,20 +284,21 @@ class IDBObjectStore final : public nsIS
   virtual JSObject* WrapObject(JSContext* aCx,
                                JS::Handle<JSObject*> aGivenProto) override;
 
  private:
   IDBObjectStore(IDBTransaction* aTransaction, const ObjectStoreSpec* aSpec);
 
   ~IDBObjectStore();
 
-  nsresult GetAddInfo(JSContext* aCx, ValueWrapper& aValueWrapper,
-                      JS::Handle<JS::Value> aKeyVal,
-                      StructuredCloneWriteInfo& aCloneWriteInfo, Key& aKey,
-                      nsTArray<IndexUpdateInfo>& aUpdateInfoArray);
+  void GetAddInfo(JSContext* aCx, ValueWrapper& aValueWrapper,
+                  JS::Handle<JS::Value> aKeyVal,
+                  StructuredCloneWriteInfo& aCloneWriteInfo, Key& aKey,
+                  nsTArray<IndexUpdateInfo>& aUpdateInfoArray,
+                  ErrorResult& aRv);
 
   already_AddRefed<IDBRequest> AddOrPut(JSContext* aCx,
                                         ValueWrapper& aValueWrapper,
                                         JS::Handle<JS::Value> aKey,
                                         bool aOverwrite, bool aFromCursor,
                                         ErrorResult& aRv);
 
   already_AddRefed<IDBRequest> DeleteInternal(JSContext* aCx,
--- a/dom/indexedDB/Key.cpp
+++ b/dom/indexedDB/Key.cpp
@@ -755,32 +755,31 @@ nsresult Key::SetFromStatement(mozIStora
   return SetFromSource(aStatement, aIndex);
 }
 
 nsresult Key::SetFromValueArray(mozIStorageValueArray* aValues,
                                 uint32_t aIndex) {
   return SetFromSource(aValues, aIndex);
 }
 
-nsresult Key::SetFromJSVal(JSContext* aCx, JS::Handle<JS::Value> aVal) {
+void Key::SetFromJSVal(JSContext* aCx, JS::Handle<JS::Value> aVal,
+                       ErrorResult& aRv) {
   mBuffer.Truncate();
 
   if (aVal.isNull() || aVal.isUndefined()) {
     Unset();
-    return NS_OK;
+    return;
   }
 
-  nsresult rv = EncodeJSVal(aCx, aVal, 0);
-  if (NS_FAILED(rv)) {
+  aRv = EncodeJSVal(aCx, aVal, 0);
+  if (aRv.Failed()) {
     Unset();
-    return rv;
+    return;
   }
   TrimBuffer();
-
-  return NS_OK;
 }
 
 nsresult Key::ToJSVal(JSContext* aCx, JS::MutableHandle<JS::Value> aVal) const {
   if (IsUnset()) {
     aVal.setUndefined();
     return NS_OK;
   }
 
--- a/dom/indexedDB/Key.h
+++ b/dom/indexedDB/Key.h
@@ -16,16 +16,19 @@ class mozIStorageValueArray;
 namespace IPC {
 
 template <typename>
 struct ParamTraits;
 
 }  // namespace IPC
 
 namespace mozilla {
+
+class ErrorResult;
+
 namespace dom {
 namespace indexedDB {
 
 class Key {
   friend struct IPC::ParamTraits<Key>;
 
   nsCString mBuffer;
 
@@ -137,17 +140,18 @@ class Key {
   }
 
   void SetFromInteger(int64_t aInt) {
     mBuffer.Truncate();
     EncodeNumber(double(aInt), eFloat);
     TrimBuffer();
   }
 
-  nsresult SetFromJSVal(JSContext* aCx, JS::Handle<JS::Value> aVal);
+  void SetFromJSVal(JSContext* aCx, JS::Handle<JS::Value> aVal,
+                    ErrorResult& aRv);
 
   nsresult ToJSVal(JSContext* aCx, JS::MutableHandle<JS::Value> aVal) const;
 
   nsresult ToJSVal(JSContext* aCx, JS::Heap<JS::Value>& aVal) const;
 
   nsresult AppendItem(JSContext* aCx, bool aFirstOfArray,
                       JS::Handle<JS::Value> aVal);