From b26df096f903fd43469aee8f9346a01311b7059f Mon Sep 17 00:00:00 2001 From: Lorenz Sieben Date: Wed, 6 Nov 2024 21:49:17 +0100 Subject: [PATCH] Fixed #1014, #1089: Skip errors we can not control --- package.json | 2 +- src/Utility/PrivacyAsyncStorage.ts | 40 ++++++++++++++++++++++-------- yarn.lock | 8 +++--- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 3ab0ef381..3ebf3a6fc 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "brutusin-json-forms": "https://github.com/brutusin/json-forms", "deepmerge": "^4.2.2", "fast-deep-equal": "^3.1.3", - "idb": "^7.0.2", + "idb": "^8.0.0", "immer": "^9.0.12", "js-cookie": "^2.2.1", "letter-generator": "^2.2.1", diff --git a/src/Utility/PrivacyAsyncStorage.ts b/src/Utility/PrivacyAsyncStorage.ts index 860078893..f7552f0c0 100644 --- a/src/Utility/PrivacyAsyncStorage.ts +++ b/src/Utility/PrivacyAsyncStorage.ts @@ -14,6 +14,15 @@ export type PrivacyAsyncStorageOption = { type KeyValueDatabase = IDBPDatabase<{ [key: string]: string }>; +const errorFilter = (e: Error) => + // These migh be caused if IndexedDB is disabled in Firefox + e.name === 'InvalidStateError' || + e.name === 'SecurityError' || + // We couldn’t identify the cause for this error, but it seems to be caused by problem in the browser, so there is + // no need to tell the user about it (we should fail gracefully anyway). + // See also: https://github.com/datenanfragen/website/issues/1014 + e.message === 'Internal Error'; + export class PrivacyAsyncStorage { #db?: typeof localStorage | KeyValueDatabase; #options: PrivacyAsyncStorageOption; @@ -49,7 +58,7 @@ export class PrivacyAsyncStorage { }, }) .catch((e: DOMException) => { - if (e.name === 'InvalidStateError') { + if (errorFilter(e)) { // Database is not writable, we are probably in Firefox' private browsing mode this.#storageType = 'localStorage'; this.#db = localStorage; @@ -144,20 +153,29 @@ export class PrivacyAsyncStorage { } static async doesStoreExist(name: string, storeName: string) { - const db: IDBPDatabase | void = await openDB(name, undefined, { blocking: () => db?.close() }).catch((e) => { - if (e.name === 'InvalidStateError' && e.name === 'VersionError') { - db?.close(); + try { + const db: IDBPDatabase | void = await openDB(name, undefined, { blocking: () => db?.close() }).catch( + (e) => { + if (errorFilter(e) || e.name === 'VersionError') { + db?.close(); + return; + } + rethrow(e, 'Error in doesStoreExist', { name, storeName, db }, t('indexeddb-error', 'error-msg')); + } + ); + + if (db) { + const result = db.objectStoreNames.contains(storeName); + db.close(); + return result; + } + } catch (e) { + if (e instanceof Error && errorFilter(e)) { return; } - rethrow(e, 'Error in doesStoreExist', { name, storeName, db }, t('indexeddb-error', 'error-msg')); - }); - - if (db) { - const result = db.objectStoreNames.contains(storeName); - db.close(); - return result; } return ( + localStorage && typeof Object.keys(localStorage).find((key) => new RegExp(`^${name}/${storeName}/`).test(key)) === 'string' ); } diff --git a/yarn.lock b/yarn.lock index 906ea9190..c58d78ece 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6925,10 +6925,10 @@ iconv-lite@^0.6.3: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" -idb@^7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/idb/-/idb-7.0.2.tgz#7a067e20dd16539938e456814b7d714ba8db3892" - integrity sha512-jjKrT1EnyZewQ/gCBb/eyiYrhGzws2FeY92Yx8qT9S9GeQAmo4JFVIiWRIfKW/6Ob9A+UDAOW9j9jn58fy2HIg== +idb@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/idb/-/idb-8.0.0.tgz#33d7ed894ed36e23bcb542fb701ad579bfaad41f" + integrity sha512-l//qvlAKGmQO31Qn7xdzagVPPaHTxXx199MhrAFuVBTPqydcPYBWjkrbv4Y0ktB+GmWOiwHl237UUOrLmQxLvw== ieee754@^1.1.13: version "1.2.1"