fix: guard localStorage.setItem('hermes-webui-model') against QuotaExceededError#1712
fix: guard localStorage.setItem('hermes-webui-model') against QuotaExceededError#171224601 wants to merge 1 commit into
Conversation
…ceededError On some setups the localStorage quota is exhausted; the bare setItem call throws an unhandled DOMException that breaks model selection and prevents the chat UI from loading. Wrap both call-sites (boot.js model-select onChange, onboarding.js _saveOnboardingDefaults) in try/catch so the error is logged to the console as a warning instead of surfacing as a fatal exception. Fixes: 'Failed to execute setItem on Storage: Setting the value of hermes-webui-model exceeded the quota.'
ac73170 to
646d48e
Compare
|
Thanks for the report and the patch — the QuotaExceededError on What's already wrapped vs what's notThe canonical write helper is function _writePersistedModelState(model, modelProvider){
const value=String(model||'').trim();
...
localStorage.setItem('hermes-webui-model', value); // line 465 — UNGUARDED
try{
localStorage.setItem(MODEL_STATE_KEY, JSON.stringify({model:value,model_provider:provider||null}));
}catch(_){}
}Whoever wrote this wrapped the second setItem (the JSON Why the boot.js change is effectively dead codeThe patched line is the if(typeof _writePersistedModelState==='function') _writePersistedModelState(modelState.model,modelState.model_provider);
else try{localStorage.setItem('hermes-webui-model',modelState.model)}catch{}
The other unguarded site the PR misses
if(startData.effective_model && S.session){
S.session.model=startData.effective_model;
...
localStorage.setItem('hermes-webui-model', startData.effective_model); // unguarded
if(typeof _writePersistedModelState==='function') _writePersistedModelState(...);This fires on every send when the gateway resolves a different effective model — which on near-quota setups is going to throw before the onboarding/onchange paths even get a chance. Suggested fixPush the try/catch one level down into the helper, then drop the now-redundant outer wraps: // static/ui.js:465
try{ localStorage.setItem('hermes-webui-model', value); }catch(_){}And add the same guard at Verification
CI passing here just means the existing tests don't cover quota-exceeded paths (none do). A unit test would need a |
|
Closed by the v0.51.5 release in PR #1713 (merged at 0ea3dfb, deployed to production). Thanks! Live on production: https://github.com/nesquena/hermes-webui/releases/tag/v0.51.5 🚀 |
4 PRs (1 surface addition, 3 fixes): - nesquena#1688 VPS resource health Insights panel (@Michaelyklam, closes nesquena#693) - nesquena#1709 preserve scroll on stream completion (@Michaelyklam, closes nesquena#1690) - nesquena#1711 hide rename tooltip on folders (@nesquena-hermes, closes nesquena#1710) - nesquena#1712 guard localStorage.setItem against QuotaExceededError (@24601) Tests: 4504 → 4527 (+23). Opus: SHIP, 6/6 verification clean. Held back: nesquena#1686 (Docker enhance) — Opus flagged sibling-repo dep that breaks standalone clones. Left open for follow-up. Co-authored-by: Michael Lam <Michaelyklam1@gmail.com> Co-authored-by: 24601 <noreply@github.com>
Problem
On some setups (localStorage near quota), the bare
localStorage.setItem('hermes-webui-model', ...)call throws an unhandledDOMException:This surfaces as a fatal exception that breaks model selection and prevents the chat UI from loading on every new chat or page load.
Fix
Wrap both call-sites in
try/catchso the error is logged to the console as aconsole.warninstead of crashing the UI. The stored value (a model ID string) is tiny — the quota failure is from overall localStorage pressure, not this key — so graceful degradation (fall back to server-side model state on next load) is the right behaviour.Files changed:
static/boot.js—$('modelSelect').onchangehandlerstatic/onboarding.js—_saveOnboardingDefaults()Test