Errors: a page the browser will not script and a non-JSON answer show raw JavaScript errors, not translated sentences #19
Labels
No labels
bug
documentation
enhancement
performance
security
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Postulo/postulo-chromium#19
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found on 2026-09-29 in a read-only review of postulo-chromium at
7998de372, by reading how the popup, the outbox and Test turn failures into sentences, and by runningreadResponse()under Node against a200HTML response.Two failures reach the person as the JavaScript engine's own English text instead of one of the extension's translated sentences. When the browser refuses to inject the reading script, the popup prints the browser's developer message. When the configured address answers a request with
2xxbut not JSON,readResponse()returnsnull, its caller reads a property ofnull, and the resultingTypeErrorbecomes what Test says and what a waiting capture stores as its problem. The person is told nothing they can act on, in no language but English.src/lib/browser.js:41-48,readCurrentTab():await ext.scripting.executeScript(...)has nocatch; only an empty result becomesRefusal("unreadable").src/lib/api.js:71-82,readResponse(): a body that fails to parse becomesnull, andif (response.ok) { return body; }hands thatnullback as success.src/lib/outbox.js:62-66,deliver():reviewUrl: result.review_urlwithresult === null.src/options.js:106-108, the Test handler:(me.scopes || [])withme === null.src/lib/i18n.js:55-63,explain(): anything without akeyis shown as itsmessage.https:page the browser will not let extensions script (the browser's own store, a host blocked by policy, a tab showing an error page),executeScriptrejects.src/popup.js:112-115catches it andexplain()prints the browser's message, such as "Cannot access contents of url …", althoughunreadable("The page could not be read. Some pages block extensions.") exists in all 40 catalogues for exactly this case./api/v1/meor/api/v1/captureswith200and an HTML page (a sign-in page served on the same origin by a proxy in front of Postulo, a captive portal, or another site at a mistyped address),readResponse()returnsnull. Test then says "Cannot read properties of null (reading 'scopes')". Delivery throws "Cannot read properties of null (reading 'review_url')";problemOf()stores it as{ message },kindOfFailure()counts it aslater(no status), and every waiting capture keeps that sentence as its reason, shown again on the captures page (src/captures.js:89) after each retry. RunningreadResponse()under Node onnew Response("<html>…", { status: 200 })returnsnull, and the property read gives exactly that message and kind.postulo-firefox/source.json), so it inherits both.readCurrentTab(), wrapexecuteScriptintry/catchand throwRefusal("unreadable"); log the original message with the error so it is not lost.readResponse(), treat a2xxwhose body did not parse or is not a JSON object as a refusal with a new key (for examplenotPostulo: "That address answered, but not as Postulo. Check the address, and any sign-in page in front of it."), thrown without astatussokindOfFailure()keeps the capture waiting. The key goes into all 40_localesat once, astest/i18n.test.mjsrequires.Done when
test/api.test.mjsasserts thatreadResponse()on a200response with an HTML body rejects with the new refusal and nostatus, and thatkindOfFailure()calls itlater.test/outbox.test.mjsasserts that a delivery answered200with HTML leaves the record waiting with{ key: "notPostulo" }as its problem, not amessage.ext.scripting.executeScriptthat rejects asserts thatreadCurrentTab()throwsRefusal("unreadable").