fix(viewer): malformed URL hash no longer bricks the whole client#186
Open
ivanmkc wants to merge 1 commit into
Open
fix(viewer): malformed URL hash no longer bricks the whole client#186ivanmkc wants to merge 1 commit into
ivanmkc wants to merge 1 commit into
Conversation
A malformed %-escape in the URL hash (e.g. "#%", "#%zz", "#foo%2") made decodeURIComponent throw URIError. readHash() runs that at module top level, so an undecodable hash aborted the ENTIRE client boot before connect() — the page froze in its static shell: status stuck "connecting…", an empty board list, a blank main pane, and (on the read-only demo) the console-toggle never removed. It survived a hard refresh because the bad fragment stays in the URL. Decode defensively via a new safeDecodeHash() helper: an undecodable hash degrades to "" (treated as no deep-link), so boot continues and the app auto-selects the first board / shows the gallery, exactly as a bare URL does. A valid hash and a bare URL were always fine — which is why a deeplink worked while the affected URL didn't.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Symptom
/w/demo/with a malformed URL-hash fragment loads a broken page: status stuck onconnecting…, an empty board list, a blank main pane, and (on the read-only demo) the Console toggle still showing. It survives a hard refresh. A valid deeplink like#ops%2Forder-fulfillmentworks fine.Root cause
readHash()runsdecodeURIComponent(location.hash…)at module top level (viewer.ts).decodeURIComponentthrowsURIError: URI malformedon a bad%-escape (#%,#%zz,#foo%2, …). The throw aborts the entire client boot beforeconnect()is ever called — so the page is frozen in its staticindex.htmlshell:connecting…connect()never ranA bare URL (empty hash) and a valid hash both decode fine — which is exactly why the deeplink worked while the affected URL didn't.
Reproduced in Chromium against both current source and the live deployment; confirmed the deployed bundle is byte-identical to source (not a stale-deploy issue).
Fix
New pure helper
safeDecodeHash()(packages/viewer/src/client/hash.ts) wraps the decode in try/catch; an undecodable hash degrades to""(treated as no deep-link), so boot continues and the app auto-selects the first board / shows the gallery — the behavior the user expected ("autoselect something … not completely fail").readHash()now calls it (covers both the top-level read and thehashchangehandler).Tests / verification
packages/viewer/test/hash.test.ts(TDD: written failing first) — normal/empty/plain hashes + malformed%-escapes never throw, degrade to""./w/demo/#%,#%zz,#foo%2: before →connecting…, 0 boards, blank,URI malformedthrow; after →● live, 15 boards, first board auto-selected, no throw. Bare URL and valid deeplink still work.Rollout
Client-side fix — the deployed Cloud Run viewer must be redeployed for it to reach users; a local dev viewer picks it up on rebuild.