Guard blob viewer computeds against missing blob
What does this MR do and why?
Addresses the sentry TypeError - "Cannot read properties of undefined (reading 'renderError')". GraphQL query resolves without a blob (deleted file, stale URL, or crawler traffic), leaving the viewer computed undefined while downstream code reads its properties without any guard.
This MR does a few things:
- adds null guards around those reads and skips viewer initialisation when no blob is returned, which also eliminates a second
endsWithTypeError in the highlight-worker setup path - the template condition is tightened so a missing blob no longer crashes; instead of leaving the file section blank, it renders a
GlEmptyStatewhere the file would be (same pattern work items use for a resolved-but-empty query):- query resolves with no blob → "File not found" with a Browse files link to the repository root
- blob resolves but carries no viewers → "Unable to display file" with a Reload page button, since this state may be transient
- A blob that resolves but carries no viewers — a schema violation because
simpleVieweris non-nullable — is reported to Sentry at info level to surface unexpected data anomalies
References
Sentry report: https://new-sentry.gitlab.net/organizations/gitlab/issues/3967899/?project=4
Screenshots or screen recordings
Blob page (/flightjs/Flight/-/blob/master/README.md) when the getBlobInfo query resolves with no blob (Playwright route mock):
Blob that resolves without viewers (route mock nulling simpleViewer/richViewer in the getBlobInfo and getBlobControls responses) — shows the reload variant, and the info-level Sentry report fires:
Normal blob page with this fix applied (unmocked response) — renders as before, no console errors:
How to set up and validate locally
-
Open any file in the repository blob view, for example
/<project>/-/blob/master/README.md, and confirm the page renders as before with no console errors. -
To simulate the crash scenario, intercept the
getBlobInfoGraphQL response (browser DevTools request override, or a Playwright route mock) and make it resolve with no blob:{ "data": { "isBinary": false, "project": { "id": "gid://gitlab/Project/1", "repository": { "empty": false, "blobs": { "nodes": [] } } } } } -
Reload the blob page. Before this change, the console shows two TypeErrors (
reading 'renderError'andreading 'endsWith') and a broken file view; after this change, there are no console errors and a "File not found" empty state renders in the file section, with a Browse files link back to the repository root. -
To see the second empty-state variant, intercept the real
getBlobInfoandgetBlobControlsresponses and setsimpleViewerandrichViewertonullon the blob node (both queries write the same blob to the Apollo cache, so both must be mocked). Reload: the file section shows "Unable to display file" with a Reload page button, and an info-level message is reported to Sentry.



