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
This commit is contained in:
Jan Varga 2020-08-20 07:32:05 +00:00
Родитель ca5114c040
Коммит 21c2588147
1 изменённых файлов: 112 добавлений и 194 удалений

Просмотреть файл

@ -2416,6 +2416,10 @@ bool FileAlreadyExists(nsresult aValue) {
return aValue == NS_ERROR_FILE_ALREADY_EXISTS; return aValue == NS_ERROR_FILE_ALREADY_EXISTS;
} }
bool FileCorrupted(nsresult aValue) {
return aValue == NS_ERROR_FILE_CORRUPTED;
}
nsresult EnsureDirectory(nsIFile* aDirectory, bool* aCreated) { nsresult EnsureDirectory(nsIFile* aDirectory, bool* aCreated) {
AssertIsOnIOThread(); AssertIsOnIOThread();
@ -6364,40 +6368,23 @@ nsresult QuotaManager::EnsureStorageIsInitialized() {
Initialization::Storage, Initialization::Storage,
[&self = *this] { return static_cast<bool>(self.mStorageConnection); }); [&self = *this] { return static_cast<bool>(self.mStorageConnection); });
auto storageFileOrErr = QM_NewLocalFile(mBasePath); QM_TRY_VAR(auto storageFile, QM_NewLocalFile(mBasePath));
if (NS_WARN_IF(storageFileOrErr.isErr())) {
return storageFileOrErr.unwrapErr();
}
nsCOMPtr<nsIFile> storageFile = storageFileOrErr.unwrap(); QM_TRY(storageFile->Append(mStorageName + kSQLiteSuffix));
nsresult rv = storageFile->Append(mStorageName + kSQLiteSuffix); QM_TRY_VAR(const auto storageFileExists,
if (NS_WARN_IF(NS_FAILED(rv))) { MOZ_TO_RESULT_INVOKE(storageFile, Exists));
return rv;
}
bool exists; if (!storageFileExists) {
rv = storageFile->Exists(&exists); QM_TRY_VAR(auto indexedDBDir, QM_NewLocalFile(mIndexedDBPath));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (!exists) { QM_TRY_VAR(const auto indexedDBDirExists,
auto indexedDBDirOrErr = QM_NewLocalFile(mIndexedDBPath); MOZ_TO_RESULT_INVOKE(indexedDBDir, Exists));
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;
}
if (indexedDBDirExists) { if (indexedDBDirExists) {
rv = UpgradeFromIndexedDBDirectoryToPersistentStorageDirectory( // TODO: Convert to QM_TRY once upgrade functions record first
// initialization attempts directly.
nsresult rv = UpgradeFromIndexedDBDirectoryToPersistentStorageDirectory(
indexedDBDir); indexedDBDir);
mInitializationInfo.RecordFirstInitializationAttempt( mInitializationInfo.RecordFirstInitializationAttempt(
Initialization::UpgradeFromIndexedDBDirectory, rv); Initialization::UpgradeFromIndexedDBDirectory, rv);
@ -6406,28 +6393,20 @@ nsresult QuotaManager::EnsureStorageIsInitialized() {
} }
} }
auto persistentStorageDirOrErr = QM_NewLocalFile(mStoragePath); QM_TRY_VAR(auto persistentStorageDir, QM_NewLocalFile(mStoragePath));
if (NS_WARN_IF(persistentStorageDirOrErr.isErr())) {
return persistentStorageDirOrErr.unwrapErr();
}
nsCOMPtr<nsIFile> persistentStorageDir = persistentStorageDirOrErr.unwrap(); QM_TRY(persistentStorageDir->Append(
nsLiteralString(PERSISTENT_DIRECTORY_NAME)));
rv = persistentStorageDir->Append( QM_TRY_VAR(const auto persistentStorageDirExists,
nsLiteralString(PERSISTENT_DIRECTORY_NAME)); MOZ_TO_RESULT_INVOKE(persistentStorageDir, Exists));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
bool persistentStorageDirExists;
rv = persistentStorageDir->Exists(&persistentStorageDirExists);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (persistentStorageDirExists) { if (persistentStorageDirExists) {
rv = UpgradeFromPersistentStorageDirectoryToDefaultStorageDirectory( // TODO: Convert to QM_TRY once upgrade functions record first
persistentStorageDir); // initialization attempts directly.
nsresult rv =
UpgradeFromPersistentStorageDirectoryToDefaultStorageDirectory(
persistentStorageDir);
mInitializationInfo.RecordFirstInitializationAttempt( mInitializationInfo.RecordFirstInitializationAttempt(
Initialization::UpgradeFromPersistentStorageDirectory, rv); Initialization::UpgradeFromPersistentStorageDirectory, rv);
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
@ -6436,46 +6415,51 @@ nsresult QuotaManager::EnsureStorageIsInitialized() {
} }
} }
nsCOMPtr<mozIStorageService> ss = // TODO: Convert to QM_TRY_VAR once we have an adapter for it.
do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID, &rv); nsCOMPtr<mozIStorageService> ss;
if (NS_WARN_IF(NS_FAILED(rv))) { {
return rv; nsresult rv;
} ss = do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID, &rv);
nsCOMPtr<mozIStorageConnection> connection;
rv = ss->OpenUnsharedDatabase(storageFile, getter_AddRefs(connection));
if (rv == NS_ERROR_FILE_CORRUPTED) {
// Nuke the database file.
rv = storageFile->Remove(false);
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
return rv; return rv;
} }
rv = ss->OpenUnsharedDatabase(storageFile, getter_AddRefs(connection));
} }
if (NS_WARN_IF(NS_FAILED(rv))) { nsCOMPtr<mozIStorageConnection> connection;
return rv;
// 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.
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. // We want extra durability for this important file.
rv = connection->ExecuteSimpleSQL("PRAGMA synchronous = EXTRA;"_ns); QM_TRY(connection->ExecuteSimpleSQL("PRAGMA synchronous = EXTRA;"_ns));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// Check to make sure that the storage version is correct. // Check to make sure that the storage version is correct.
int32_t storageVersion; QM_TRY_VAR(auto storageVersion,
rv = connection->GetSchemaVersion(&storageVersion); MOZ_TO_RESULT_INVOKE(connection, GetSchemaVersion));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// Hacky downgrade logic! // Hacky downgrade logic!
// If we see major.minor of 3.0, downgrade it to be 2.1. // If we see major.minor of 3.0, downgrade it to be 2.1.
if (storageVersion == kHackyPreDowngradeStorageVersion) { if (storageVersion == kHackyPreDowngradeStorageVersion) {
storageVersion = kHackyPostDowngradeStorageVersion; 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))) { if (NS_WARN_IF(NS_FAILED(rv))) {
MOZ_ASSERT(false, "Downgrade didn't take."); MOZ_ASSERT(false, "Downgrade didn't take.");
return rv; return rv;
@ -6483,6 +6467,7 @@ nsresult QuotaManager::EnsureStorageIsInitialized() {
} }
if (GetMajorStorageVersion(storageVersion) > kMajorStorageVersion) { if (GetMajorStorageVersion(storageVersion) > kMajorStorageVersion) {
// TODO: This should use QM_TRY too.
NS_WARNING("Unable to initialize storage, version is too high!"); NS_WARNING("Unable to initialize storage, version is too high!");
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
@ -6490,28 +6475,18 @@ nsresult QuotaManager::EnsureStorageIsInitialized() {
if (storageVersion < kStorageVersion) { if (storageVersion < kStorageVersion) {
const bool newDatabase = !storageVersion; const bool newDatabase = !storageVersion;
auto storageDirOrErr = QM_NewLocalFile(mStoragePath); QM_TRY_VAR(auto storageDir, QM_NewLocalFile(mStoragePath));
if (NS_WARN_IF(storageDirOrErr.isErr())) {
return storageDirOrErr.unwrapErr();
}
nsCOMPtr<nsIFile> storageDir = storageDirOrErr.unwrap(); QM_TRY_VAR(const auto storageDirExists,
MOZ_TO_RESULT_INVOKE(storageDir, Exists));
rv = storageDir->Exists(&exists); const bool newDirectory = !storageDirExists;
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
const bool newDirectory = !exists;
if (newDatabase) { if (newDatabase) {
// Set the page size first. // Set the page size first.
if (kSQLitePageSizeOverride) { if (kSQLitePageSizeOverride) {
rv = connection->ExecuteSimpleSQL(nsPrintfCString( QM_TRY(connection->ExecuteSimpleSQL(nsPrintfCString(
"PRAGMA page_size = %" PRIu32 ";", kSQLitePageSizeOverride)); "PRAGMA page_size = %" PRIu32 ";", kSQLitePageSizeOverride)));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} }
} }
@ -6522,26 +6497,23 @@ nsresult QuotaManager::EnsureStorageIsInitialized() {
// The upgrade loop below can only be avoided when there's no database and // The upgrade loop below can only be avoided when there's no database and
// no storage yet (e.g. new profile). // no storage yet (e.g. new profile).
if (newDatabase && newDirectory) { if (newDatabase && newDirectory) {
rv = CreateTables(connection); QM_TRY(CreateTables(connection));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
MOZ_ASSERT(NS_SUCCEEDED(connection->GetSchemaVersion(&storageVersion))); MOZ_ASSERT(NS_SUCCEEDED(connection->GetSchemaVersion(&storageVersion)));
MOZ_ASSERT(storageVersion == kStorageVersion); MOZ_ASSERT(storageVersion == kStorageVersion);
rv = connection->ExecuteSimpleSQL( QM_TRY(connection->ExecuteSimpleSQL(
nsLiteralCString("INSERT INTO database (cache_version) " nsLiteralCString("INSERT INTO database (cache_version) "
"VALUES (0)")); "VALUES (0)")));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} else { } else {
// This logic needs to change next time we change the storage! // This logic needs to change next time we change the storage!
static_assert(kStorageVersion == int32_t((2 << 16) + 3), static_assert(kStorageVersion == int32_t((2 << 16) + 3),
"Upgrade function needed due to storage version increase."); "Upgrade function needed due to storage version increase.");
while (storageVersion != kStorageVersion) { while (storageVersion != kStorageVersion) {
// TODO: Convert to QM_TRY once upgrade functions record first
// initialization attempts directly.
nsresult rv;
if (storageVersion == 0) { if (storageVersion == 0) {
rv = UpgradeStorageFrom0_0To1_0(connection); rv = UpgradeStorageFrom0_0To1_0(connection);
mInitializationInfo.RecordFirstInitializationAttempt( mInitializationInfo.RecordFirstInitializationAttempt(
@ -6563,6 +6535,7 @@ nsresult QuotaManager::EnsureStorageIsInitialized() {
mInitializationInfo.RecordFirstInitializationAttempt( mInitializationInfo.RecordFirstInitializationAttempt(
Initialization::UpgradeStorageFrom2_2To2_3, rv); Initialization::UpgradeStorageFrom2_2To2_3, rv);
} else { } else {
// TODO: This should use QM_TRY too.
NS_WARNING( NS_WARNING(
"Unable to initialize storage, no upgrade path is " "Unable to initialize storage, no upgrade path is "
"available!"); "available!");
@ -6573,68 +6546,49 @@ nsresult QuotaManager::EnsureStorageIsInitialized() {
return rv; return rv;
} }
rv = connection->GetSchemaVersion(&storageVersion); QM_TRY_VAR(storageVersion,
if (NS_WARN_IF(NS_FAILED(rv))) { MOZ_TO_RESULT_INVOKE(connection, GetSchemaVersion));
return rv;
}
} }
MOZ_ASSERT(storageVersion == kStorageVersion); MOZ_ASSERT(storageVersion == kStorageVersion);
} }
rv = transaction.Commit(); QM_TRY(transaction.Commit());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} }
if (CachedNextGenLocalStorageEnabled()) { if (CachedNextGenLocalStorageEnabled()) {
// TODO: Use QM_TRY_VAR once the return type is Result<V, E>.
nsCOMPtr<mozIStorageConnection> connection; nsCOMPtr<mozIStorageConnection> connection;
bool newlyCreated; bool newlyCreated;
rv = CreateLocalStorageArchiveConnection(getter_AddRefs(connection), QM_TRY(CreateLocalStorageArchiveConnection(getter_AddRefs(connection),
newlyCreated); newlyCreated));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
uint32_t version = 0; uint32_t version = 0;
if (!newlyCreated) { if (!newlyCreated) {
// TODO: Use QM_TRY_VAR once the return type is Result<V, E>.
bool initialized; bool initialized;
rv = IsLocalStorageArchiveInitialized(connection, initialized); QM_TRY(IsLocalStorageArchiveInitialized(connection, initialized));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (initialized) { if (initialized) {
rv = LoadLocalStorageArchiveVersion(connection, version); // TODO: Use QM_TRY_VAR once the return type is Result<V, E>.
if (NS_WARN_IF(NS_FAILED(rv))) { QM_TRY(LoadLocalStorageArchiveVersion(connection, version));
return rv;
}
} }
} }
if (version > kLocalStorageArchiveVersion) { if (version > kLocalStorageArchiveVersion) {
rv = DowngradeLocalStorageArchive(connection); QM_TRY(DowngradeLocalStorageArchive(connection));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = LoadLocalStorageArchiveVersion(connection, version); // TODO: Use QM_TRY_VAR once the return type is Result<V, E>.
if (NS_WARN_IF(NS_FAILED(rv))) { QM_TRY(LoadLocalStorageArchiveVersion(connection, version));
return rv;
}
MOZ_ASSERT(version == kLocalStorageArchiveVersion); MOZ_ASSERT(version == kLocalStorageArchiveVersion);
} else if (version != kLocalStorageArchiveVersion) { } else if (version != kLocalStorageArchiveVersion) {
if (newlyCreated) { if (newlyCreated) {
MOZ_ASSERT(version == 0); MOZ_ASSERT(version == 0);
rv = InitializeLocalStorageArchive(connection, QM_TRY(InitializeLocalStorageArchive(connection,
kLocalStorageArchiveVersion); kLocalStorageArchiveVersion));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} else { } else {
static_assert(kLocalStorageArchiveVersion == 4, static_assert(kLocalStorageArchiveVersion == 4,
"Upgrade function needed due to LocalStorage archive " "Upgrade function needed due to LocalStorage archive "
@ -6642,44 +6596,34 @@ nsresult QuotaManager::EnsureStorageIsInitialized() {
while (version != kLocalStorageArchiveVersion) { while (version != kLocalStorageArchiveVersion) {
if (version < 4) { if (version < 4) {
rv = UpgradeLocalStorageArchiveFromLessThan4To4(connection); QM_TRY(UpgradeLocalStorageArchiveFromLessThan4To4(connection));
} /* else if (version == 4) { } /* else if (version == 4) {
rv = UpgradeLocalStorageArchiveFrom4To5(connection); QM_TRY(UpgradeLocalStorageArchiveFrom4To5(connection));
} */ } */
else { else {
// TODO: This should use QM_TRY too.
QM_WARNING( QM_WARNING(
"Unable to initialize LocalStorage archive, no upgrade path is " "Unable to initialize LocalStorage archive, no upgrade path is "
"available!"); "available!");
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
if (NS_WARN_IF(NS_FAILED(rv))) { // TODO: Use QM_TRY_VAR once the return type is Result<V, E>.
return rv; QM_TRY(LoadLocalStorageArchiveVersion(connection, version));
}
rv = LoadLocalStorageArchiveVersion(connection, version);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} }
MOZ_ASSERT(version == kLocalStorageArchiveVersion); MOZ_ASSERT(version == kLocalStorageArchiveVersion);
} }
} }
} else { } else {
rv = MaybeRemoveLocalStorageData(); QM_TRY(MaybeRemoveLocalStorageData());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} }
bool cacheUsable = true; bool cacheUsable = true;
// TODO: Use QM_TRY_VAR once the return type is Result<V, E>.
int32_t cacheVersion; int32_t cacheVersion;
rv = LoadCacheVersion(connection, cacheVersion); QM_TRY(LoadCacheVersion(connection, cacheVersion));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (cacheVersion > kCacheVersion) { if (cacheVersion > kCacheVersion) {
cacheUsable = false; cacheUsable = false;
@ -6690,20 +6634,14 @@ nsresult QuotaManager::EnsureStorageIsInitialized() {
connection, false, mozIStorageConnection::TRANSACTION_IMMEDIATE); connection, false, mozIStorageConnection::TRANSACTION_IMMEDIATE);
if (newCache) { if (newCache) {
rv = CreateCacheTables(connection); QM_TRY(CreateCacheTables(connection));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
MOZ_ASSERT(NS_SUCCEEDED(LoadCacheVersion(connection, cacheVersion))); MOZ_ASSERT(NS_SUCCEEDED(LoadCacheVersion(connection, cacheVersion)));
MOZ_ASSERT(cacheVersion == kCacheVersion); MOZ_ASSERT(cacheVersion == kCacheVersion);
rv = connection->ExecuteSimpleSQL( QM_TRY(connection->ExecuteSimpleSQL(
nsLiteralCString("INSERT INTO cache (valid, build_id) " nsLiteralCString("INSERT INTO cache (valid, build_id) "
"VALUES (0, '')")); "VALUES (0, '')")));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsCOMPtr<mozIStorageStatement> insertStmt; nsCOMPtr<mozIStorageStatement> insertStmt;
@ -6711,30 +6649,21 @@ nsresult QuotaManager::EnsureStorageIsInitialized() {
if (insertStmt) { if (insertStmt) {
MOZ_ALWAYS_SUCCEEDS(insertStmt->Reset()); MOZ_ALWAYS_SUCCEEDS(insertStmt->Reset());
} else { } else {
rv = connection->CreateStatement( // TODO: Can we simplify this syntax ?
nsLiteralCString("INSERT INTO repository (id, name) " QM_TRY_VAR(insertStmt,
"VALUES (:id, :name)"), ToResultInvoke<nsCOMPtr<mozIStorageStatement>>(
getter_AddRefs(insertStmt)); std::mem_fn(&mozIStorageConnection::CreateStatement),
if (NS_WARN_IF(NS_FAILED(rv))) { connection,
return rv; nsLiteralCString("INSERT INTO repository (id, name) "
} "VALUES (:id, :name)")));
} }
rv = insertStmt->BindInt32ByName("id"_ns, persistenceType); QM_TRY(insertStmt->BindInt32ByName("id"_ns, persistenceType));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = insertStmt->BindUTF8StringByName( QM_TRY(insertStmt->BindUTF8StringByName(
"name"_ns, PersistenceTypeToString(persistenceType)); "name"_ns, PersistenceTypeToString(persistenceType)));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = insertStmt->Execute(); QM_TRY(insertStmt->Execute());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} }
} else { } else {
// This logic needs to change next time we change the cache! // This logic needs to change next time we change the cache!
@ -6743,38 +6672,27 @@ nsresult QuotaManager::EnsureStorageIsInitialized() {
while (cacheVersion != kCacheVersion) { while (cacheVersion != kCacheVersion) {
/* if (cacheVersion == 1) { /* if (cacheVersion == 1) {
rv = UpgradeCacheFrom1To2(connection); QM_TRY(UpgradeCacheFrom1To2(connection));
} else */ } else */
{ {
// TODO: This should use QM_TRY too.
QM_WARNING( QM_WARNING(
"Unable to initialize cache, no upgrade path is available!"); "Unable to initialize cache, no upgrade path is available!");
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
if (NS_WARN_IF(NS_FAILED(rv))) { // TODO: Use QM_TRY_VAR once the return type is Result<V, E>.
return rv; QM_TRY(LoadCacheVersion(connection, cacheVersion));
}
rv = LoadCacheVersion(connection, cacheVersion);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} }
MOZ_ASSERT(cacheVersion == kCacheVersion); MOZ_ASSERT(cacheVersion == kCacheVersion);
} }
rv = transaction.Commit(); QM_TRY(transaction.Commit());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} }
if (cacheUsable && gInvalidateQuotaCache) { if (cacheUsable && gInvalidateQuotaCache) {
rv = InvalidateCache(connection); QM_TRY(InvalidateCache(connection));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
gInvalidateQuotaCache = false; gInvalidateQuotaCache = false;
} }