Skip to content

fix(explorer): show 'no results found' instead of hanging on an unfetchable tx - #7783

Merged
alfetopito merged 2 commits into
cowprotocol:developfrom
tenderdeve:fix/7390-explorer-tx-search-hang
Jul 3, 2026
Merged

alfetopito merged 2 commits into
cowprotocol:developfrom
tenderdeve:fix/7390-explorer-tx-search-hang

Conversation

@tenderdeve

@tenderdeve tenderdeve commented Jul 1, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #7390

Searching a tx whose details can't be fetched leaves the explorer stuck on "Loading transaction details" forever instead of showing the SearchNotFound screen.

getTxOrders races the prod and staging (barn) lookups with Promise.any, but only the barn leg had a timeout. Promise.any stays pending until one promise fulfils or all reject, so when the prod request never responds, the race never settles — isLoading stays true and the widget's redirect-to-SearchNotFound (which is gated on !isLoading) can never fire.

Wrap the prod leg in the same 12s timeout as barn (withProdTimeout). A hanging prod request now rejects on timeout, the race resolves ([] when the other env is empty), and the existing empty-result path redirects to "no results found".

Tests in operatorApi.test.ts: prod-times-out + staging-empty resolves to [] (the reported hang), and both-envs-time-out rejects instead of hanging.

Note: the sibling env-race helpers in this file (getOrder, getTrades, competition lookups) share the same unbounded-prod shape; happy to bound those in a follow-up if you'd like, kept this PR to the tx-search path.

Summary by CodeRabbit

  • Bug Fixes

    • Added timeouts to PROD transaction-order requests so they no longer hang indefinitely.
    • Improved fallback behavior when one or both environments are slow or unresponsive, helping requests resolve or fail more predictably.
  • Tests

    • Added coverage for timeout and fallback scenarios to verify behavior when PROD stalls and when both environments time out.

getTxOrders races the prod and staging (barn) order lookups with Promise.any,
but only the barn leg was wrapped in a timeout. Promise.any stays pending until
a promise fulfils or all reject, so when the prod request never responds (an
"impossible to fetch" tx), the race never settles: isLoading stays true and the
tx-details view is stuck on "Loading transaction details" forever, never
redirecting to the SearchNotFound screen.

Wrap the prod leg in the same 12s timeout as barn. A hanging prod request now
rejects on timeout, the race resolves ([] when the other env is empty), and the
existing empty-result path redirects to "no results found".
@vercel

vercel Bot commented Jul 1, 2026

Copy link
Copy Markdown

@tenderdeve is attempting to deploy a commit to the cow-dev Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jul 1, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Adds a withProdTimeout helper to operatorApi.ts that time-bounds PROD requests using the existing shared timeout constant, applies it to the PROD call in getTxOrders, updates related documentation, and adds tests validating timeout/fallback and rejection behavior.

Changes

PROD Timeout Fix

Layer / File(s) Summary
Add PROD timeout wrapper to getTxOrders
apps/explorer/src/api/operator/operatorApi.ts
Adds withProdTimeout using the shared ENV_REQUEST_TIMEOUT_MS constant, updates the getTxOrders doc comment, and wraps the PROD SDK call so it is time-bounded like the BARN call.
Timeout behavior tests
apps/explorer/src/test/api/operator/operatorApi.test.ts
Adds fake-timer tests confirming getTxOrders resolves to an empty array when only PROD hangs and rejects when both PROD and staging hang.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • cowprotocol/cowswap#7583: Companion change adding withBarnTimeout to the BARN branch of the same getTxOrders function with matching test coverage.

Suggested reviewers: fairlighteth, limitofzero

Poem

A hop, a timer, tick and race,
PROD and BARN now keep their pace.
No hang, no stall, no endless wait —
Empty array or clean rejection, sealed by fate.
🐇⏱️ carrots for the timeout gate!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main fix: preventing hung tx searches from showing no results.
Description check ✅ Passed The description covers the issue, change, tests, and background, with only minor template-format omissions.
Linked Issues check ✅ Passed The PR addresses #7390 by time-bounding the prod tx lookup so the search flow can resolve to the no-results path.
Out of Scope Changes check ✅ Passed All code changes stay within the tx-search timeout fix and its tests; no unrelated scope is introduced.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@elena-zh elena-zh added the trigger-preview Add to a fork PR to trigger CF-pages preview. See https://github.com/cowprotocol/cowswap/pull/7615 label Jul 1, 2026
@github-actions

github-actions Bot commented Jul 1, 2026 •

Copy link
Copy Markdown
Contributor

Cloudflare Pages preview mirror

Preview branch URL: https://github.com/cowprotocol/cowswap/tree/cf-preview/pr-7783
Mirror PR: #7789
Cloudflare Pages preview links will be posted on the mirror PR by the Cloudflare Pages GitHub integration once builds complete.

Source fork branch: tenderdeve/cowswap:fix/7390-explorer-tx-search-hang
Approval target SHA: 71c5f3f6a36b
Last mirrored SHA: 00027aae66bb
Last comment update: @limitofzero at 2026-07-02T20:43:51.578Z

  • Sync Cloudflare preview to approval target commit

@github-actions github-actions Bot removed the trigger-preview Add to a fork PR to trigger CF-pages preview. See https://github.com/cowprotocol/cowswap/pull/7615 label Jul 1, 2026
@vercel
vercel Bot temporarily deployed to Preview – storybook July 1, 2026 11:50 Inactive
@vercel
vercel Bot temporarily deployed to Preview – widget-configurator July 1, 2026 11:51 Inactive
@vercel
vercel Bot temporarily deployed to Preview – cowfi July 1, 2026 11:52 Inactive

@elena-zh elena-zh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@elena-zh
elena-zh requested a review from limitofzero July 1, 2026 13:36

@limitofzero limitofzero left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@limitofzero
limitofzero enabled auto-merge (squash) July 2, 2026 20:43

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/explorer/src/api/operator/operatorApi.ts (1)

22-29: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider consolidating withBarnTimeout/withProdTimeout.

Both helpers are identical apart from the hardcoded env label; a single parameterized helper would remove the duplication.

♻️ Optional consolidation
-function withBarnTimeout<T>(promise: Promise<T>, operation: string): Promise<T> {
-  return withTimeout(promise, ENV_REQUEST_TIMEOUT_MS, `${operation}: BARN`)
-}
-
-function withProdTimeout<T>(promise: Promise<T>, operation: string): Promise<T> {
-  return withTimeout(promise, ENV_REQUEST_TIMEOUT_MS, `${operation}: PROD`)
-}
+function withEnvTimeout<T>(promise: Promise<T>, operation: string, env: 'PROD' | 'BARN'): Promise<T> {
+  return withTimeout(promise, ENV_REQUEST_TIMEOUT_MS, `${operation}: ${env}`)
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/explorer/src/api/operator/operatorApi.ts` around lines 22 - 29,
Consolidate the duplicated timeout wrappers in operatorApi.ts by replacing
withBarnTimeout and withProdTimeout with a single parameterized helper that
accepts the env label and delegates to withTimeout; keep the existing behavior
by passing the appropriate label string where each helper is currently used, and
update any call sites to use the shared helper instead of two near-identical
functions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@apps/explorer/src/api/operator/operatorApi.ts`:
- Around line 22-29: Consolidate the duplicated timeout wrappers in
operatorApi.ts by replacing withBarnTimeout and withProdTimeout with a single
parameterized helper that accepts the env label and delegates to withTimeout;
keep the existing behavior by passing the appropriate label string where each
helper is currently used, and update any call sites to use the shared helper
instead of two near-identical functions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 816433a4-7ec0-4e58-922d-cb3e62d829a0

📥 Commits

Reviewing files that changed from the base of the PR and between f6e65f4 and 71c5f3f.

📒 Files selected for processing (2)
  • apps/explorer/src/api/operator/operatorApi.ts
  • apps/explorer/src/test/api/operator/operatorApi.test.ts

@alfetopito
alfetopito disabled auto-merge July 3, 2026 13:25
@alfetopito
alfetopito merged commit 4ba77d4 into cowprotocol:develop Jul 3, 2026
5 of 12 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 3, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Explorer: show 'no results found' when impossible to fetch a TX details

4 participants