tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 13aa8ab1d77ff5c42b93c8b1ac06353adf939de3
parent 04b66025cf4f6065f50fbac3da5e7fed42ca7640
Author: Rob Wu <rob@robwu.nl>
Date:   Wed,  1 Oct 2025 17:21:12 +0000

Bug 1990529 - Log unsanitized error on internal storage.sync r=rpl

Differential Revision: https://phabricator.services.mozilla.com/D266019

Diffstat:
Mtoolkit/components/extensions/ExtensionStorageSync.sys.mjs | 18+++++++++++-------
Mtoolkit/components/extensions/test/xpcshell/head_storage.js | 4++--
Mtoolkit/components/extensions/test/xpcshell/test_ext_storage_sync.js | 50++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 63 insertions(+), 9 deletions(-)

diff --git a/toolkit/components/extensions/ExtensionStorageSync.sys.mjs b/toolkit/components/extensions/ExtensionStorageSync.sys.mjs @@ -70,13 +70,17 @@ export class ExtensionStorageSync { } catch (ex) { // The only "public" exception here is for quota failure - all others // are sanitized. - let sanitized = - ex instanceof lazy.QuotaError - ? // The same message as the local IDB implementation - "QuotaExceededError: storage.sync API call exceeded its quota limitations." - : // The standard, generic extension error. - "An unexpected error occurred"; - throw new lazy.ExtensionUtils.ExtensionError(sanitized); + if (ex instanceof lazy.QuotaError) { + // The same message as the local IDB implementation + throw new lazy.ExtensionUtils.ExtensionError( + "QuotaExceededError: storage.sync API call exceeded its quota limitations." + ); + } + Cu.reportError(ex); + // The standard, generic extension error. + throw new lazy.ExtensionUtils.ExtensionError( + "An unexpected error occurred" + ); } } diff --git a/toolkit/components/extensions/test/xpcshell/head_storage.js b/toolkit/components/extensions/test/xpcshell/head_storage.js @@ -788,7 +788,7 @@ async function check_storage_sync_getBytesInUse(area, expectQuota) { if (expectQuota) { await browser.test.assertRejects( impl.set({ x: value + "x" }), - /QuotaExceededError/, + "QuotaExceededError: storage.sync API call exceeded its quota limitations.", "Got a rejection with the expected error message" ); // MAX_ITEMS @@ -800,7 +800,7 @@ async function check_storage_sync_getBytesInUse(area, expectQuota) { await impl.set(ob); // should work. await browser.test.assertRejects( impl.set({ straw: "camel's back" }), // exceeds MAX_ITEMS - /QuotaExceededError/, + "QuotaExceededError: storage.sync API call exceeded its quota limitations.", "Got a rejection with the expected error message" ); // QUOTA_BYTES is being already tested for the underlying StorageSyncService diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_storage_sync.js b/toolkit/components/extensions/test/xpcshell/test_ext_storage_sync.js @@ -34,3 +34,53 @@ add_task(async function test_storage_onChanged_event_page() { add_task(async function test_storage_session_getBytesInUse() { await test_get_bytes_in_use("sync"); }); + +add_task(async function test_storage_sync_sanitizes_internal_error() { + const extension = ExtensionTestUtils.loadExtension({ + manifest: { + permissions: ["storage"], + browser_specific_settings: { gecko: { id: "test@storage-sync-err" } }, + }, + background() { + browser.test.onMessage.addListener(async msg => { + browser.test.assertEq(msg, "call_storage_sync", "Expected message"); + await browser.test.assertRejects( + browser.storage.sync.get(null), + "An unexpected error occurred", + "Internal error from storage.sync implementation is sanitized" + ); + browser.test.sendMessage("done"); + }); + // Call any storage.sync API, to make sure that recordSyncQuotaTelemetry + // in parent/ext-storage.js is called, so that its logic is skipped when + // we call storage.sync.get(null) again in this test. Otherwise the mock + // below that fakes an error will be tripped and cause + // recordSyncQuotaTelemetry to raise an unrejected promise rejection, + // which causes the test to fail. + browser.storage.sync.get(null).then(() => { + browser.test.sendMessage("ready_to_call_sync"); + }); + }, + }); + await extension.startup(); + await extension.awaitMessage("ready_to_call_sync"); + const { messages } = await promiseConsoleOutput(async () => { + const { storageSyncService } = ChromeUtils.importESModule( + "resource://gre/modules/ExtensionStorageComponents.sys.mjs" + ); + const orig = storageSyncService._storageAreaPromise; + storageSyncService._storageAreaPromise = Promise.reject( + new Error("Some fake internal error") + ); + try { + extension.sendMessage("call_storage_sync"); + await extension.awaitMessage("done"); + } finally { + storageSyncService._storageAreaPromise = orig; + } + }); + AddonTestUtils.checkMessages(messages, { + expected: [{ message: /Some fake internal error/ }], + }); + await extension.unload(); +});