fix: prevent "Something went wrong" screen flash on failed spend query#93752
fix: prevent "Something went wrong" screen flash on failed spend query#93752nabi-ebrahimi wants to merge 2 commits into
Conversation
Codecov Report❌ Looks like you've decreased code coverage for some files. Please write tests to increase, or at least maintain, the existing level of code coverage. See our documentation here for how to interpret this table.
|
|
@QichenZhu Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 574f2f24b6
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (validGroupBy || (shouldCalculateTotals && searchResults?.search?.count === undefined)) { | ||
| shouldRetrySearchWithTotalsOrGroupedRef.current = true; | ||
| } | ||
| if (offset === 0 || offset === searchResults?.search?.offset || !isFocused || isOffline || searchResults?.search?.isLoading) { |
There was a problem hiding this comment.
Re-run empty searches after reconnecting
When a user has a cached empty search open while offline and then reconnects, this new guard always returns for offset === 0, so the removed comingBackOnlineWithNoResults path no longer refreshes the snapshot. useSearchPageSetup() does not compensate because isSearchDataLoaded() treats existing empty data as loaded, so users can remain stuck on a stale empty state until they change the query or navigate away.
Useful? React with 👍 / 👎.
| const shouldRefreshBehindRHP = isChat || hasManualHighlightTransactionIDs; | ||
| const isSearchStillActive = isFocused || (isSearchTopmostFullScreenRoute() && shouldRefreshBehindRHP); | ||
| if (!isSearchStillActive || isOffline) { | ||
| hasPendingSearchRef.current = true; | ||
| hasPendingSearchRef.current = isOffline || shouldRefreshBehindRHP; |
There was a problem hiding this comment.
Keep pending refreshes for expense changes behind RHP
When a non-chat Search page is covered by an RHP and a matching transaction is added or removed while the RHP is open, isFocused is false and shouldRefreshBehindRHP is also false unless a manual highlight was registered, so this drops the pending refresh instead of preserving it. After the RHP closes, previousTransactions has already advanced and the hook no longer sees an ID change, leaving the expense search snapshot stale until another search is triggered.
Useful? React with 👍 / 👎.
Explanation of Change
This PR prevents Search from re-running an already resolved initial search request.
useSearchPageSetup()already owns the initialoffset: 0request for the current search query. TheSearchcomponent was also issuing a mount/focus search for the same query. When that query failed, the duplicate request optimistically clearederrors, causing the error page to unmount and the loading skeleton to appear again.This change removes that redundant initial fetch path from
Search, so failed search snapshots remain stable and theSomething went wrongpage stays visible.Fixed Issues
$ #92462
PROPOSAL:#92462(comment)
Tests
Spend>Expenses.type:chat category:abcd.Offline tests
N/A. This issue is about duplicate Search requests after a failed online search response.
QA Steps
Same as tests.
// TODO: These must be filled out, or the issue title must include "[No QA]."
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Screen.Recording.2026-06-17.at.2.11.29.AM.mov
Android: mWeb Chrome
Screen.Recording.2026-06-17.at.2.17.33.AM.mov
iOS: Native
Screen.Recording.2026-06-17.at.1.44.17.AM.mov
iOS: mWeb Safari
Screen.Recording.2026-06-17.at.1.52.47.AM.mov
MacOS: Chrome / Safari
Screen.Recording.2026-06-17.at.2.24.39.AM.mov