Theseus 0.3.65: Updates panel can't silently fatal into "Loading…" any more

Settings › General › Updates used to stay on "Loading…" forever if anything
earlier in the shared C.get().then((s)=>…) init threw, or if the version IPC
rejected — the .catch(()=>{}) on the version fetch swallowed it. Users then
had no in-app way to run "Check for updates", because the button sits in the
same panel.

Panel init now wraps in its own try, surfaces the actual error on the status
line (missing IPC / fetch rejection / init failure), and keeps the Check for
Updates button functional even when the earlier version read fails. Toolbar
chip is unaffected either way — the auto-updater runs independently.
This commit is contained in:
Silent Mode 2026-10-02 22:45:36 +02:00
parent 565972a23b
commit a02deffe61
2 changed files with 39 additions and 22 deletions

View file

@ -1,6 +1,6 @@
{ {
"name": "theseus-navigator", "name": "theseus-navigator",
"version": "0.3.64", "version": "0.3.65",
"license": "MPL-2.0", "license": "MPL-2.0",
"description": "Theseus Navigator — a browser that follows the thread. By Silent Mode, a Deviant project.", "description": "Theseus Navigator — a browser that follows the thread. By Silent Mode, a Deviant project.",
"author": "Silent Mode", "author": "Silent Mode",

View file

@ -1786,18 +1786,31 @@
// Fires an IPC that un-dismisses any lingering session chip and hits the // Fires an IPC that un-dismisses any lingering session chip and hits the
// release manifest. Renders either "you're on the latest (vN.M.O)" or // release manifest. Renders either "you're on the latest (vN.M.O)" or
// "vX.Y.Z is available — the update chip in the toolbar will offer it". // "vX.Y.Z is available — the update chip in the toolbar will offer it".
// Wrap the Updates panel init in its own try — any earlier failure in
// this big C.get().then((s)=>…) block would otherwise leave the panel
// stuck on "Loading…" forever (silent `.catch(()=>{})` on the version
// fetch). We also always react to the fetch's reject, instead of
// swallowing it, so the user has a status line they can act on.
try {
const updStatus = document.getElementById("updStatus"); const updStatus = document.getElementById("updStatus");
// Show the current version by default so the user doesn't have to // Show the current version by default so the user doesn't have to
// click "Check for updates" just to find out which Theseus they're on. // click "Check for updates" just to find out which Theseus they're on.
if (C && C.appVersion) C.appVersion().then((v) => { if (C && C.appVersion) {
if (v) updStatus.textContent = `You're on v${v}.`; C.appVersion().then((v) => {
}).catch(() => {}); updStatus.textContent = v ? `You're on v${v}.` : "Version unavailable — try Check for updates.";
}).catch((e) => {
updStatus.textContent = "Could not read version: " + (e?.message || e) + " — try Check for updates.";
});
} else {
updStatus.textContent = "This build is missing the version IPC — restart Theseus to refresh the panel.";
}
const updCheck = document.getElementById("updCheck"); const updCheck = document.getElementById("updCheck");
updCheck.onclick = async () => { if (updCheck) updCheck.onclick = async () => {
const orig = updCheck.textContent; const orig = updCheck.textContent;
updCheck.disabled = true; updCheck.textContent = "Checking…"; updCheck.disabled = true; updCheck.textContent = "Checking…";
updStatus.textContent = "Checking…"; updStatus.textContent = "Checking…";
try { try {
if (!C.recheckUpdate) throw new Error("recheck-update IPC not exposed");
const r = await C.recheckUpdate(); const r = await C.recheckUpdate();
if (r && r.updateAvailable && r.updateAvailable.version) { if (r && r.updateAvailable && r.updateAvailable.version) {
updStatus.innerHTML = `<b style="color:var(--acid-text)">v${r.updateAvailable.version}</b> is available — the update chip in the toolbar will offer it.`; updStatus.innerHTML = `<b style="color:var(--acid-text)">v${r.updateAvailable.version}</b> is available — the update chip in the toolbar will offer it.`;
@ -1807,6 +1820,10 @@
} catch (e) { updStatus.textContent = "Check failed: " + (e?.message || e); } } catch (e) { updStatus.textContent = "Check failed: " + (e?.message || e); }
finally { updCheck.disabled = false; updCheck.textContent = orig; } finally { updCheck.disabled = false; updCheck.textContent = orig; }
}; };
} catch (e) {
try { document.getElementById("updStatus").textContent = "Updates panel init failed: " + (e?.message || e); } catch {}
console.error("Updates panel init failed:", e);
}
// ---- Passwords section: three states (setup / locked / unlocked) --------- // ---- Passwords section: three states (setup / locked / unlocked) ---------
// The vault lives in main.js — this UI just calls IPC. No plaintext ever // The vault lives in main.js — this UI just calls IPC. No plaintext ever