Keeping a capture: a full storage quota makes Keep do nothing, with no message #16

Closed
opened 2026-10-01 10:47:15 +00:00 by tiagoagueda · 0 comments
Owner

Found on 2026-09-29 in a read-only review of postulo-chromium at 7998de372, following every storage write from a button.

Related to postulo/postulo-firefox#1.

Captures and their slimmed pages live in storage.local, which Chromium caps at 10 MB without unlimitedStorage (the manifest no longer asks for it). A kept page stays until it is sent, and nothing sends a kept capture by itself. Once the quota is reached, storage.local.set rejects. The handlers that add a capture have no try, so the rejection is unhandled and the click does nothing visible; Send shows the browser's raw, untranslated quota message.

  • Where:
    • src/popup.js:133-141, the Keep in this browser handler: const record = await save("kept"); outside any try.
    • src/popup.js:310-318, Keep for the ticked postings of a results page, through savePicked and store.addMany.
    • src/captures.js:145-161, Save in the list's editor, when the corrected fields are longer than before.
    • src/lib/store.js:59-68 (add) and :76-101 (addMany), one set() of record, page and index that fails as a whole.
    • src/popup.js:143-180, Send: save("waiting") is inside the try, and explain() (src/lib/i18n.js:55-63) falls back to error.message, the browser's English text.
    • PRIVACY.md:25-27: "at most 512 KB", while MAX_PAGE (src/lib/parse.js:841) is 512 × 1024 UTF-16 characters and the quota counts bytes of the JSON-serialised value, so a page in a non-Latin script, or one heavy with quoted attributes, takes more.
  • What happens: someone using the extension without a server, as the README invites ("Capturing does not need step 1 or 2"), or keeping postings to triage later, collects a few dozen kept captures of heavy pages. The next Keep leaves the popup on the form with no message and no log entry; when the popup closes, the reviewed fields are gone.
  • Why it matters: a capture the person believes they kept is silently lost, and nothing tells them why or what to do.
  • Fix: wrap the writing handlers in try/catch and report a translated sentence through say(), for example "This browser's storage for Postulo is full: send or delete some captures." (a new key in all 40 catalogues); recognise the quota error in explain() rather than showing its text. Optionally show the space used (storage.local.getBytesInUse) on Captures in this browser. Say "characters" in PRIVACY.md, or measure the page in bytes.

Delete, Clear the ones sent and Hold back only shrink what is stored, so the quota does not refuse them.

Done when

  • A test in test/outbox.test.mjs (or a new test/store.test.mjs) gives makeStore an area whose set rejects with a quota error and asserts that the error reaching the caller carries a translatable key; the Keep, Keep-ticked and editor Save handlers each catch it and call say(..., true).
Found on 2026-09-29 in a read-only review of postulo-chromium at 7998de372, following every storage write from a button. Related to postulo/postulo-firefox#1. Captures and their slimmed pages live in `storage.local`, which Chromium caps at 10 MB without `unlimitedStorage` (the manifest no longer asks for it). A kept page stays until it is sent, and nothing sends a kept capture by itself. Once the quota is reached, `storage.local.set` rejects. The handlers that add a capture have no `try`, so the rejection is unhandled and the click does nothing visible; Send shows the browser's raw, untranslated quota message. - **Where:** - `src/popup.js:133-141`, the *Keep in this browser* handler: `const record = await save("kept");` outside any `try`. - `src/popup.js:310-318`, *Keep* for the ticked postings of a results page, through `savePicked` and `store.addMany`. - `src/captures.js:145-161`, *Save* in the list's editor, when the corrected fields are longer than before. - `src/lib/store.js:59-68` (`add`) and `:76-101` (`addMany`), one `set()` of record, page and index that fails as a whole. - `src/popup.js:143-180`, *Send*: `save("waiting")` is inside the `try`, and `explain()` (`src/lib/i18n.js:55-63`) falls back to `error.message`, the browser's English text. - `PRIVACY.md:25-27`: "at most 512 KB", while `MAX_PAGE` (`src/lib/parse.js:841`) is 512 × 1024 UTF-16 characters and the quota counts bytes of the JSON-serialised value, so a page in a non-Latin script, or one heavy with quoted attributes, takes more. - **What happens:** someone using the extension without a server, as the README invites ("Capturing does not need step 1 or 2"), or keeping postings to triage later, collects a few dozen kept captures of heavy pages. The next *Keep* leaves the popup on the form with no message and no log entry; when the popup closes, the reviewed fields are gone. - **Why it matters:** a capture the person believes they kept is silently lost, and nothing tells them why or what to do. - **Fix:** wrap the writing handlers in `try`/`catch` and report a translated sentence through `say()`, for example "This browser's storage for Postulo is full: send or delete some captures." (a new key in all 40 catalogues); recognise the quota error in `explain()` rather than showing its text. Optionally show the space used (`storage.local.getBytesInUse`) on *Captures in this browser*. Say "characters" in `PRIVACY.md`, or measure the page in bytes. Delete, *Clear the ones sent* and *Hold back* only shrink what is stored, so the quota does not refuse them. ## Done when - A test in `test/outbox.test.mjs` (or a new `test/store.test.mjs`) gives `makeStore` an area whose `set` rejects with a quota error and asserts that the error reaching the caller carries a translatable key; the Keep, Keep-ticked and editor Save handlers each catch it and call `say(..., true)`.
tiagoagueda added this to the 0.6.0 milestone 2026-10-01 10:47:15 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Postulo/postulo-chromium#16
No description provided.