Skip to content

fix(thread/github): degrade a non-JSON sandbox-git response instead of raw SyntaxError - #6358

Open
pedrofrxncx wants to merge 1 commit into
mainfrom
fix/sandbox-git-non-json-error-w2
Open

fix(thread/github): degrade a non-JSON sandbox-git response instead of raw SyntaxError#6358
pedrofrxncx wants to merge 1 commit into
mainfrom
fix/sandbox-git-non-json-error-w2

Conversation

@pedrofrxncx

@pedrofrxncx pedrofrxncx commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Source: bug found while auditing the GitHub tooling layer (apps/web/src/components/thread/github/). This is the same failure-mode this repo has already fixed at several other HTTP boundaries (see apps/api/src/tools/github/graphql.ts's parseGraphqlBody, and the merged "degrade a malformed 2xx body instead of raw SyntaxError" lane, e.g. #6289/#6293/#6161) — sandbox-git-api.ts's shared parseJson helper never got the same treatment.

Payoff: every Fast Preview git call (/git/status, /git/diff, /git/publish, /git/rebase, /git/discard, /git/suggest-commit, /git/judge-review) goes through sandboxFetch + parseJson. A gateway/proxy hiccup between the browser and the sandbox daemon (a 502/504 HTML error page, or an empty body on a dropped connection) is not guaranteed to be JSON even when it's a real response, and res.json() throws a raw, unhandled SyntaxError in that case ("Unexpected token '<'") instead of the typed SandboxGitError every caller in this file branches on — including isSandboxUnreachable, which backs off polling instead of hammering a downed sandbox. A raw SyntaxError bypasses that backoff and surfaces as an opaque toast.

Fix: parseJson now reads the body as text and tolerates a JSON-parse failure on both the success and failure path, always throwing SandboxGitError (carrying the real HTTP status) instead of letting JSON.parse's exception escape uncaught. Behavior for a well-formed JSON response (ok or error-shaped) is unchanged.

Regression test: added to the existing sandbox-git-api.test.ts (which already covers this file's pure logic) — a non-JSON error page on a non-2xx status, and a non-JSON body on a 2xx status, both now reject with SandboxGitError carrying the response's status instead of an unhandled SyntaxError.

To verify: bun test apps/web/src/components/thread/github/sandbox-git-api.test.ts

Locally ran: bun run fmt, cd apps/web && bunx tsc --noEmit, the targeted test file above (76 pass), and bunx oxlint on both changed files (0 warnings/errors). Full CI validates the rest.


Summary by cubic

Degrades non-JSON responses from sandbox git endpoints to a typed SandboxGitError with HTTP status instead of leaking a raw SyntaxError. This restores backoff and consistent error handling across Fast Preview git operations; behavior for valid JSON is unchanged.

  • parseJson now reads the body as text, attempts JSON parse, and throws SandboxGitError(status) on parse failure or any non-2xx response.
  • Exports SandboxGitError and parseJson; adds tests covering non-JSON bodies (2xx and non-2xx) and JSON error shapes.
  • No call-site changes required; callers that branch on SandboxGitError (e.g., isSandboxUnreachable) now back off on gateway errors instead of showing opaque toasts.

Written for commit 4c8d5fc. Summary will update on new commits.

Review in cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant