fix(OUT-4109): await SWR mutate refetches and enrich fetcher errors - #1437
fix(OUT-4109): await SWR mutate refetches and enrich fetcher errors#1437cursor[bot] wants to merge 2 commits into
Conversation
Await unawaited mutate() calls in ActivityWrapper, Subtasks, and Subtemplates so post-mutation fetcher() failures are caught by existing try/catch blocks instead of surfacing as unhandled promise rejections. Enrich fetcher errors with HTTP status, URL, and response body snippet for actionable Sentry events. Co-authored-by: Neil Raina <[email protected]>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
… from fetcher errors The unawaited mutate() fix missed the fire-and-forget debounceMutate(cacheKey) paths, which reject the same way when revalidation fails, and it made two non-async handlers await, so the branch did not typecheck. The enriched error also embedded the full URL, which carries the Copilot session token — that would have shipped a live credential to Sentry on every failed fetch. Log the path only and attach the status, which swr-config's onErrorRetry already reads to skip retrying 404s. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Y4tF84tzJW7Bo1DehsDX22
|
Deployment failed for project tasks-app with the following error: Learn More: https://vercel.link/multiple-function-regions |
|
Superseded by #1439, which keeps just the rejection handling. Dropping from this branch: the Happy to do the error-message enrichment as its own small PR later if we want these Sentry events to carry a status and path. |
Sentry
Error: An error occurred while fetching the data.is asrc/utils/fetcher.tsthrow escaping as an unhandled rejection: SWRmutate()promises weren't awaited or caught, so the surroundingtry/catchnever saw them. OUT-4109 — also covers OUT-4107 (same root cause; #1436 can be closed).What to look at:
src/utils/fetcher.ts— the error now carries the request path, not the URL. The URL's query string holds the live Copilot session token, and the first pass of this PR would have shipped it to Sentry on every failed fetch. It also attachesstatus, whichswr-config.ts:onErrorRetryalready reads to skip retrying 404s — that check was dead until now, so 404s stop being retried 3×.ActivityWrapper.tsx/Subtasks.tsx/Subtemplates.tsx— two rejection paths per file: the optimisticmutate(...)(now awaited inside the existingtry/catch) and the fire-and-forgetdebounceMutate(cacheKey)revalidation (now.catch-ed). Only the first was fixed initially.Subtasks.tsx/Subtemplates.tsx—handleSubTaskCreation/handleSubtemplateCreationare nowasync; addingawaitwithout this brokeyarn tsc.Verified:
yarn tsc,yarn lint:check(0 errors),yarn prettier:check,yarn test src/utils/fetcher.test.ts(4/4). Not verified: no manual browser run against a failing API — the optimistic rollback behaviour on error is unchanged by this diff but wasn't exercised end to end.