Bug 1658324 - Convert most of the error handling in QuotaManager::EnsureStorageIsInitialized to QM_TRY/QM_TRY_VAR; r=dom-workers-and-storage-reviewers,sg
authorJan Varga <jvarga@mozilla.com>
Thu, 20 Aug 2020 13:32:21 +0000
changeset 610143 711d1a3b5b3a5e98dce8906b6fd97684c066e419
parent 610142 d92766e56d92847d4639466c0d5aea89252371f8
child 610144 325966c58ad27142169c9794bd551ad8fadbc091
push id13553
push userffxbld-merge
push dateMon, 24 Aug 2020 12:51:36 +0000
treeherdermozilla-beta@a54f8b5d0977 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdom-workers-and-storage-reviewers, sg
bugs1658324
milestone81.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 1658324 - Convert most of the error handling in QuotaManager::EnsureStorageIsInitialized to QM_TRY/QM_TRY_VAR; r=dom-workers-and-storage-reviewers,sg Differential Revision: https://phabricator.services.mozilla.com/D86560
dom/quota/ActorsParent.cpp
--- a/dom/quota/ActorsParent.cpp
+++ b/dom/quota/ActorsParent.cpp
@@ -2411,16 +2411,20 @@ int64_t GetLastModifiedTime(nsIFile* aFi
 
   return timestamp;
 }
 
 bool FileAlreadyExists(nsresult aValue) {
   return aValue == NS_ERROR_FILE_ALREADY_EXISTS;
 }
 
+bool FileCorrupted(nsresult aValue) {
+  return aValue == NS_ERROR_FILE_CORRUPTED;
+}
+
 nsresult EnsureDirectory(nsIFile* aDirectory, bool* aCreated) {
   AssertIsOnIOThread();
 
   QM_TRY_VAR(const bool exists,
              ToResult(aDirectory->Create(nsIFile::DIRECTORY_TYPE, 0755),
                       FileAlreadyExists));
 
   if (exists) {
@@ -6359,194 +6363,163 @@ nsresult QuotaManager::EnsureStorageIsIn
     mInitializationInfo.AssertInitializationAttempted(Initialization::Storage);
     return NS_OK;
   }
 
   const auto autoRecord = mInitializationInfo.RecordFirstInitializationAttempt(
       Initialization::Storage,
       [&self = *this] { return static_cast<bool>(self.mStorageConnection); });
 
-  auto storageFileOrErr = QM_NewLocalFile(mBasePath);
-  if (NS_WARN_IF(storageFileOrErr.isErr())) {
-    return storageFileOrErr.unwrapErr();
-  }
-
-  nsCOMPtr<nsIFile> storageFile = storageFileOrErr.unwrap();
-
-  nsresult rv = storageFile->Append(mStorageName + kSQLiteSuffix);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  bool exists;
-  rv = storageFile->Exists(&exists);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  if (!exists) {
-    auto indexedDBDirOrErr = QM_NewLocalFile(mIndexedDBPath);
-    if (NS_WARN_IF(indexedDBDirOrErr.isErr())) {
-      return indexedDBDirOrErr.unwrapErr();
-    }
-
-    nsCOMPtr<nsIFile> indexedDBDir = indexedDBDirOrErr.unwrap();
-
-    bool indexedDBDirExists;
-    rv = indexedDBDir->Exists(&indexedDBDirExists);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
+  QM_TRY_VAR(auto storageFile, QM_NewLocalFile(mBasePath));
+
+  QM_TRY(storageFile->Append(mStorageName + kSQLiteSuffix));
+
+  QM_TRY_VAR(const auto storageFileExists,
+             ToResultInvoke(storageFile, &nsIFile::Exists));
+
+  if (!storageFileExists) {
+    QM_TRY_VAR(auto indexedDBDir, QM_NewLocalFile(mIndexedDBPath));
+
+    QM_TRY_VAR(const auto indexedDBDirExists,
+               ToResultInvoke(indexedDBDir, &nsIFile::Exists));
 
     if (indexedDBDirExists) {
-      rv = UpgradeFromIndexedDBDirectoryToPersistentStorageDirectory(
+      // TODO: Convert to QM_TRY once upgrade functions record first
+      //       initialization attempts directly.
+      nsresult rv = UpgradeFromIndexedDBDirectoryToPersistentStorageDirectory(
           indexedDBDir);
       mInitializationInfo.RecordFirstInitializationAttempt(
           Initialization::UpgradeFromIndexedDBDirectory, rv);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
     }
 
-    auto persistentStorageDirOrErr = QM_NewLocalFile(mStoragePath);
-    if (NS_WARN_IF(persistentStorageDirOrErr.isErr())) {
-      return persistentStorageDirOrErr.unwrapErr();
-    }
-
-    nsCOMPtr<nsIFile> persistentStorageDir = persistentStorageDirOrErr.unwrap();
-
-    rv = persistentStorageDir->Append(
-        nsLiteralString(PERSISTENT_DIRECTORY_NAME));
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    bool persistentStorageDirExists;
-    rv = persistentStorageDir->Exists(&persistentStorageDirExists);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
+    QM_TRY_VAR(auto persistentStorageDir, QM_NewLocalFile(mStoragePath));
+
+    QM_TRY(persistentStorageDir->Append(
+        nsLiteralString(PERSISTENT_DIRECTORY_NAME)));
+
+    QM_TRY_VAR(const auto persistentStorageDirExists,
+               ToResultInvoke(persistentStorageDir, &nsIFile::Exists));
 
     if (persistentStorageDirExists) {
-      rv = UpgradeFromPersistentStorageDirectoryToDefaultStorageDirectory(
-          persistentStorageDir);
+      // TODO: Convert to QM_TRY once upgrade functions record first
+      //       initialization attempts directly.
+      nsresult rv =
+          UpgradeFromPersistentStorageDirectoryToDefaultStorageDirectory(
+              persistentStorageDir);
       mInitializationInfo.RecordFirstInitializationAttempt(
           Initialization::UpgradeFromPersistentStorageDirectory, rv);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
     }
   }
 
-  nsCOMPtr<mozIStorageService> ss =
-      do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID, &rv);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
+  // TODO: Convert to QM_TRY_VAR once we have an adapter for it.
+  nsCOMPtr<mozIStorageService> ss;
+  {
+    nsresult rv;
+    ss = do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID, &rv);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
   }
 
   nsCOMPtr<mozIStorageConnection> connection;
-  rv = ss->OpenUnsharedDatabase(storageFile, getter_AddRefs(connection));
-  if (rv == NS_ERROR_FILE_CORRUPTED) {
+
+  // TODO: Result<V, E> could have own mapping function for filtering out
+  //       NS_ERROR_FILE_CORRUPTED.
+  // TODO: We can then use ToResultInvoke here (like below).
+  QM_TRY_VAR(const auto corrupted,
+             ToResult(ss->OpenUnsharedDatabase(storageFile,
+                                               getter_AddRefs(connection)),
+                      FileCorrupted));
+
+  if (corrupted) {
     // Nuke the database file.
-    rv = storageFile->Remove(false);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    rv = ss->OpenUnsharedDatabase(storageFile, getter_AddRefs(connection));
-  }
-
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
+    QM_TRY(storageFile->Remove(false));
+
+    // TODO: Can we simplify this syntax ?
+    QM_TRY_VAR(connection,
+               ToResultInvoke<nsCOMPtr<mozIStorageConnection>>(
+                   std::mem_fn(&mozIStorageService::OpenUnsharedDatabase), ss,
+                   storageFile));
   }
 
   // We want extra durability for this important file.
-  rv = connection->ExecuteSimpleSQL("PRAGMA synchronous = EXTRA;"_ns);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
+  QM_TRY(connection->ExecuteSimpleSQL("PRAGMA synchronous = EXTRA;"_ns));
 
   // Check to make sure that the storage version is correct.
-  int32_t storageVersion;
-  rv = connection->GetSchemaVersion(&storageVersion);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
+  QM_TRY_VAR(
+      auto storageVersion,
+      ToResultInvoke(connection, &mozIStorageConnection::GetSchemaVersion));
 
   // Hacky downgrade logic!
   // If we see major.minor of 3.0, downgrade it to be 2.1.
   if (storageVersion == kHackyPreDowngradeStorageVersion) {
     storageVersion = kHackyPostDowngradeStorageVersion;
-    rv = connection->SetSchemaVersion(storageVersion);
+    // TODO: Convert to QM_TRY once we have support for additional cleanup
+    //       function.
+    nsresult rv = connection->SetSchemaVersion(storageVersion);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       MOZ_ASSERT(false, "Downgrade didn't take.");
       return rv;
     }
   }
 
   if (GetMajorStorageVersion(storageVersion) > kMajorStorageVersion) {
+    // TODO: This should use QM_TRY too.
     NS_WARNING("Unable to initialize storage, version is too high!");
     return NS_ERROR_FAILURE;
   }
 
   if (storageVersion < kStorageVersion) {
     const bool newDatabase = !storageVersion;
 
-    auto storageDirOrErr = QM_NewLocalFile(mStoragePath);
-    if (NS_WARN_IF(storageDirOrErr.isErr())) {
-      return storageDirOrErr.unwrapErr();
-    }
-
-    nsCOMPtr<nsIFile> storageDir = storageDirOrErr.unwrap();
-
-    rv = storageDir->Exists(&exists);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    const bool newDirectory = !exists;
+    QM_TRY_VAR(auto storageDir, QM_NewLocalFile(mStoragePath));
+
+    QM_TRY_VAR(const auto storageDirExists,
+               ToResultInvoke(storageDir, &nsIFile::Exists));
+
+    const bool newDirectory = !storageDirExists;
 
     if (newDatabase) {
       // Set the page size first.
       if (kSQLitePageSizeOverride) {
-        rv = connection->ExecuteSimpleSQL(nsPrintfCString(
-            "PRAGMA page_size = %" PRIu32 ";", kSQLitePageSizeOverride));
-        if (NS_WARN_IF(NS_FAILED(rv))) {
-          return rv;
-        }
+        QM_TRY(connection->ExecuteSimpleSQL(nsPrintfCString(
+            "PRAGMA page_size = %" PRIu32 ";", kSQLitePageSizeOverride)));
       }
     }
 
     mozStorageTransaction transaction(
         connection, false, mozIStorageConnection::TRANSACTION_IMMEDIATE);
 
     // An upgrade method can upgrade the database, the storage or both.
     // The upgrade loop below can only be avoided when there's no database and
     // no storage yet (e.g. new profile).
     if (newDatabase && newDirectory) {
-      rv = CreateTables(connection);
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return rv;
-      }
+      QM_TRY(CreateTables(connection));
 
       MOZ_ASSERT(NS_SUCCEEDED(connection->GetSchemaVersion(&storageVersion)));
       MOZ_ASSERT(storageVersion == kStorageVersion);
 
-      rv = connection->ExecuteSimpleSQL(
+      QM_TRY(connection->ExecuteSimpleSQL(
           nsLiteralCString("INSERT INTO database (cache_version) "
-                           "VALUES (0)"));
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return rv;
-      }
+                           "VALUES (0)")));
     } else {
       // This logic needs to change next time we change the storage!
       static_assert(kStorageVersion == int32_t((2 << 16) + 3),
                     "Upgrade function needed due to storage version increase.");
 
       while (storageVersion != kStorageVersion) {
+        // TODO: Convert to QM_TRY once upgrade functions record first
+        //       initialization attempts directly.
+        nsresult rv;
         if (storageVersion == 0) {
           rv = UpgradeStorageFrom0_0To1_0(connection);
           mInitializationInfo.RecordFirstInitializationAttempt(
               Initialization::UpgradeStorageFrom0_0To1_0, rv);
         } else if (storageVersion == MakeStorageVersion(1, 0)) {
           rv = UpgradeStorageFrom1_0To2_0(connection);
           mInitializationInfo.RecordFirstInitializationAttempt(
               Initialization::UpgradeStorageFrom1_0To2_0, rv);
@@ -6558,228 +6531,175 @@ nsresult QuotaManager::EnsureStorageIsIn
           rv = UpgradeStorageFrom2_1To2_2(connection);
           mInitializationInfo.RecordFirstInitializationAttempt(
               Initialization::UpgradeStorageFrom2_1To2_2, rv);
         } else if (storageVersion == MakeStorageVersion(2, 2)) {
           rv = UpgradeStorageFrom2_2To2_3(connection);
           mInitializationInfo.RecordFirstInitializationAttempt(
               Initialization::UpgradeStorageFrom2_2To2_3, rv);
         } else {
+          // TODO: This should use QM_TRY too.
           NS_WARNING(
               "Unable to initialize storage, no upgrade path is "
               "available!");
           return NS_ERROR_FAILURE;
         }
 
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
         }
 
-        rv = connection->GetSchemaVersion(&storageVersion);
-        if (NS_WARN_IF(NS_FAILED(rv))) {
-          return rv;
-        }
+        QM_TRY_VAR(storageVersion,
+                   ToResultInvoke(connection,
+                                  &mozIStorageConnection::GetSchemaVersion));
       }
 
       MOZ_ASSERT(storageVersion == kStorageVersion);
     }
 
-    rv = transaction.Commit();
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
+    QM_TRY(transaction.Commit());
   }
 
   if (CachedNextGenLocalStorageEnabled()) {
+    // TODO: Use QM_TRY_VAR once the return type is Result<V, E>.
     nsCOMPtr<mozIStorageConnection> connection;
     bool newlyCreated;
-    rv = CreateLocalStorageArchiveConnection(getter_AddRefs(connection),
-                                             newlyCreated);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
+    QM_TRY(CreateLocalStorageArchiveConnection(getter_AddRefs(connection),
+                                               newlyCreated));
 
     uint32_t version = 0;
 
     if (!newlyCreated) {
+      // TODO: Use QM_TRY_VAR once the return type is Result<V, E>.
       bool initialized;
-      rv = IsLocalStorageArchiveInitialized(connection, initialized);
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return rv;
-      }
+      QM_TRY(IsLocalStorageArchiveInitialized(connection, initialized));
 
       if (initialized) {
-        rv = LoadLocalStorageArchiveVersion(connection, version);
-        if (NS_WARN_IF(NS_FAILED(rv))) {
-          return rv;
-        }
+        // TODO: Use QM_TRY_VAR once the return type is Result<V, E>.
+        QM_TRY(LoadLocalStorageArchiveVersion(connection, version));
       }
     }
 
     if (version > kLocalStorageArchiveVersion) {
-      rv = DowngradeLocalStorageArchive(connection);
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return rv;
-      }
-
-      rv = LoadLocalStorageArchiveVersion(connection, version);
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return rv;
-      }
+      QM_TRY(DowngradeLocalStorageArchive(connection));
+
+      // TODO: Use QM_TRY_VAR once the return type is Result<V, E>.
+      QM_TRY(LoadLocalStorageArchiveVersion(connection, version));
 
       MOZ_ASSERT(version == kLocalStorageArchiveVersion);
     } else if (version != kLocalStorageArchiveVersion) {
       if (newlyCreated) {
         MOZ_ASSERT(version == 0);
 
-        rv = InitializeLocalStorageArchive(connection,
-                                           kLocalStorageArchiveVersion);
-        if (NS_WARN_IF(NS_FAILED(rv))) {
-          return rv;
-        }
+        QM_TRY(InitializeLocalStorageArchive(connection,
+                                             kLocalStorageArchiveVersion));
       } else {
         static_assert(kLocalStorageArchiveVersion == 4,
                       "Upgrade function needed due to LocalStorage archive "
                       "version increase.");
 
         while (version != kLocalStorageArchiveVersion) {
           if (version < 4) {
-            rv = UpgradeLocalStorageArchiveFromLessThan4To4(connection);
+            QM_TRY(UpgradeLocalStorageArchiveFromLessThan4To4(connection));
           } /* else if (version == 4) {
-            rv = UpgradeLocalStorageArchiveFrom4To5(connection);
+            QM_TRY(UpgradeLocalStorageArchiveFrom4To5(connection));
           } */
           else {
+            // TODO: This should use QM_TRY too.
             QM_WARNING(
                 "Unable to initialize LocalStorage archive, no upgrade path is "
                 "available!");
             return NS_ERROR_FAILURE;
           }
 
-          if (NS_WARN_IF(NS_FAILED(rv))) {
-            return rv;
-          }
-
-          rv = LoadLocalStorageArchiveVersion(connection, version);
-          if (NS_WARN_IF(NS_FAILED(rv))) {
-            return rv;
-          }
+          // TODO: Use QM_TRY_VAR once the return type is Result<V, E>.
+          QM_TRY(LoadLocalStorageArchiveVersion(connection, version));
         }
 
         MOZ_ASSERT(version == kLocalStorageArchiveVersion);
       }
     }
   } else {
-    rv = MaybeRemoveLocalStorageData();
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
+    QM_TRY(MaybeRemoveLocalStorageData());
   }
 
   bool cacheUsable = true;
 
+  // TODO: Use QM_TRY_VAR once the return type is Result<V, E>.
   int32_t cacheVersion;
-  rv = LoadCacheVersion(connection, cacheVersion);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
+  QM_TRY(LoadCacheVersion(connection, cacheVersion));
 
   if (cacheVersion > kCacheVersion) {
     cacheUsable = false;
   } else if (cacheVersion != kCacheVersion) {
     const bool newCache = !cacheVersion;
 
     mozStorageTransaction transaction(
         connection, false, mozIStorageConnection::TRANSACTION_IMMEDIATE);
 
     if (newCache) {
-      rv = CreateCacheTables(connection);
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return rv;
-      }
+      QM_TRY(CreateCacheTables(connection));
 
       MOZ_ASSERT(NS_SUCCEEDED(LoadCacheVersion(connection, cacheVersion)));
       MOZ_ASSERT(cacheVersion == kCacheVersion);
 
-      rv = connection->ExecuteSimpleSQL(
+      QM_TRY(connection->ExecuteSimpleSQL(
           nsLiteralCString("INSERT INTO cache (valid, build_id) "
-                           "VALUES (0, '')"));
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return rv;
-      }
+                           "VALUES (0, '')")));
 
       nsCOMPtr<mozIStorageStatement> insertStmt;
 
       for (const PersistenceType persistenceType : kAllPersistenceTypes) {
         if (insertStmt) {
           MOZ_ALWAYS_SUCCEEDS(insertStmt->Reset());
         } else {
-          rv = connection->CreateStatement(
-              nsLiteralCString("INSERT INTO repository (id, name) "
-                               "VALUES (:id, :name)"),
-              getter_AddRefs(insertStmt));
-          if (NS_WARN_IF(NS_FAILED(rv))) {
-            return rv;
-          }
+          // TODO: Can we simplify this syntax ?
+          QM_TRY_VAR(insertStmt,
+                     ToResultInvoke<nsCOMPtr<mozIStorageStatement>>(
+                         std::mem_fn(&mozIStorageConnection::CreateStatement),
+                         connection,
+                         nsLiteralCString("INSERT INTO repository (id, name) "
+                                          "VALUES (:id, :name)")));
         }
 
-        rv = insertStmt->BindInt32ByName("id"_ns, persistenceType);
-        if (NS_WARN_IF(NS_FAILED(rv))) {
-          return rv;
-        }
-
-        rv = insertStmt->BindUTF8StringByName(
-            "name"_ns, PersistenceTypeToString(persistenceType));
-        if (NS_WARN_IF(NS_FAILED(rv))) {
-          return rv;
-        }
-
-        rv = insertStmt->Execute();
-        if (NS_WARN_IF(NS_FAILED(rv))) {
-          return rv;
-        }
+        QM_TRY(insertStmt->BindInt32ByName("id"_ns, persistenceType));
+
+        QM_TRY(insertStmt->BindUTF8StringByName(
+            "name"_ns, PersistenceTypeToString(persistenceType)));
+
+        QM_TRY(insertStmt->Execute());
       }
     } else {
       // This logic needs to change next time we change the cache!
       static_assert(kCacheVersion == 1,
                     "Upgrade function needed due to cache version increase.");
 
       while (cacheVersion != kCacheVersion) {
         /* if (cacheVersion == 1) {
-          rv = UpgradeCacheFrom1To2(connection);
+          QM_TRY(UpgradeCacheFrom1To2(connection));
         } else */
         {
+          // TODO: This should use QM_TRY too.
           QM_WARNING(
               "Unable to initialize cache, no upgrade path is available!");
           return NS_ERROR_FAILURE;
         }
 
-        if (NS_WARN_IF(NS_FAILED(rv))) {
-          return rv;
-        }
-
-        rv = LoadCacheVersion(connection, cacheVersion);
-        if (NS_WARN_IF(NS_FAILED(rv))) {
-          return rv;
-        }
+        // TODO: Use QM_TRY_VAR once the return type is Result<V, E>.
+        QM_TRY(LoadCacheVersion(connection, cacheVersion));
       }
 
       MOZ_ASSERT(cacheVersion == kCacheVersion);
     }
 
-    rv = transaction.Commit();
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
+    QM_TRY(transaction.Commit());
   }
 
   if (cacheUsable && gInvalidateQuotaCache) {
-    rv = InvalidateCache(connection);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
+    QM_TRY(InvalidateCache(connection));
 
     gInvalidateQuotaCache = false;
   }
 
   mStorageConnection = connection;
   mCacheUsable = cacheUsable;
 
   return NS_OK;