W11-C3: Trade submission hangs silently with no timeout or error when offline #173

Closed
opened 2026-05-20 18:37:44 +00:00 by totdking · 10 comments
totdking commented 2026-05-20 18:37:44 +00:00 (Migrated from gitlab.com)
No description provided.
totdking commented 2026-05-20 19:06:30 +00:00 (Migrated from gitlab.com)

Issue Summary

When the network is offline and the trader attempts to place or cancel a trade, clicking the submit button triggers the wallet interaction sequence but the request hangs indefinitely. No spinner-with-timeout, no "request cancelled" message, and no error state is shown. The trader cannot tell whether the transaction was submitted, is pending, or was dropped.


Reproduction Steps

  1. Start the app with LocalTerra running and connect a wallet
  2. Navigate to /trade, select a pair, fill in a valid price and amount
  3. Set DevTools Network to Offline
  4. Click Place Limit
  5. Observe: the wallet prompt may appear, approve it
  6. Observe the UI — no error, no success, no timeout message; the action just hangs

Expected Behavior

After a configurable timeout (e.g. 30 seconds), the submission should cancel and surface an actionable error: "Could not broadcast the transaction. Check your connection and try again." The submit button should re-enable so the trader can retry.


Actual Behavior

The submission hangs indefinitely. No timeout fires, no error is shown, and the submit button state does not recover. The trader has no signal about what happened to their order.


Screen Record

Screen Recording 2026-05-20 at 19.54.25.mov{width=900 height=544}


Environment Details

Field Value
OS macOS (Apple M1 Pro, 14-inch)
Browser Google Chrome (desktop)
Viewport ~1440px desktop
Network localterra (local Docker), DevTools Offline mode + indexer domain blocked
Frontend VITE_NETWORK=local npm run dev

Wallet / Device Details

  • Wallet: simulated wallet
  • Wallet state: Connected — localterra

Severity / Impact

P2 UX. A silent hang after a trade submit is one of the worst outcomes for trader trust — they cannot tell if funds moved. On mainnet with real assets this creates genuine risk: a trader may attempt to cancel an order they believe is stuck, not knowing whether it was broadcast. Found under W11-C3 (Contract query failures — Updates and Trader use dimensions).

cc: @PlasticDigits i

### Issue Summary When the network is offline and the trader attempts to place or cancel a trade, clicking the submit button triggers the wallet interaction sequence but the request hangs indefinitely. No spinner-with-timeout, no "request cancelled" message, and no error state is shown. The trader cannot tell whether the transaction was submitted, is pending, or was dropped. --- ### Reproduction Steps 1. Start the app with LocalTerra running and connect a wallet 2. Navigate to `/trade`, select a pair, fill in a valid price and amount 3. Set DevTools Network to **Offline** 4. Click **Place Limit** 5. Observe: the wallet prompt may appear, approve it 6. Observe the UI — no error, no success, no timeout message; the action just hangs --- ### Expected Behavior After a configurable timeout (e.g. 30 seconds), the submission should cancel and surface an actionable error: _"Could not broadcast the transaction. Check your connection and try again."_ The submit button should re-enable so the trader can retry. --- ### Actual Behavior The submission hangs indefinitely. No timeout fires, no error is shown, and the submit button state does not recover. The trader has no signal about what happened to their order. --- ## Screen Record ![Screen Recording 2026-05-20 at 19.54.25.mov](/uploads/c75d33eccf3a416c66ca0ff086aacee8/Screen_Recording_2026-05-20_at_19.54.25.mov){width=900 height=544} --- ### Environment Details | Field | Value | |-------|-------| | OS | macOS (Apple M1 Pro, 14-inch) | | Browser | Google Chrome (desktop) | | Viewport | \~1440px desktop | | Network | `localterra` (local Docker), DevTools Offline mode + indexer domain blocked | | Frontend | `VITE_NETWORK=local npm run dev` | --- ### Wallet / Device Details - **Wallet:** simulated wallet - **Wallet state:** Connected — localterra --- ### Severity / Impact **P2 UX.** A silent hang after a trade submit is one of the worst outcomes for trader trust — they cannot tell if funds moved. On mainnet with real assets this creates genuine risk: a trader may attempt to cancel an order they believe is stuck, not knowing whether it was broadcast. Found under **W11-C3** (Contract query failures — Updates and Trader use dimensions). cc: @PlasticDigits i
totdking commented 2026-05-20 20:29:14 +00:00 (Migrated from gitlab.com)

mentioned in issue #116

mentioned in issue #116
PlasticDigits commented 2026-05-21 12:13:51 +00:00 (Migrated from gitlab.com)

mentioned in commit 3b1a22362d

mentioned in commit 3b1a22362d523e136183effc93cb535551c5c3b2
PlasticDigits commented 2026-05-21 12:14:45 +00:00 (Migrated from gitlab.com)

Fix landed on main (c86553f)

Trade and other on-chain submits were hanging forever when the wallet RPC / LCD poll stalled (e.g. DevTools Offline after approving a limit place). The shared Terra tx layer now caps broadcastTx and pollTx so React Query mutations fail and re-enable submit buttons.

What changed

  • executeTerraContract / executeTerraContractMulti wrap wallet.broadcastTx (default 30s, VITE_TERRA_TX_BROADCAST_TIMEOUT_MS) and wallet.pollTx (default 90s, VITE_TERRA_TX_POLL_TIMEOUT_MS) via withPromiseTimeout.
  • Broadcast timeout copy: "Could not broadcast the transaction. Check your connection and try again."
  • Poll timeout copy: "Transaction confirmation timed out. Check your connection and try again."
  • Applies to limit place/cancel, swaps, pool txs — not only /trade.

Docs / agent playbooks

Verification checklist

  • cd frontend-dapp && npm run test -- --run src/services/terraclassic/__tests__/transactions.test.ts src/utils/__tests__/withPromiseTimeout.test.ts
  • Local: VITE_NETWORK=local npm run dev, Simulated Wallet, /trade → valid limit → DevTools Offline → Place limit → approve if prompted
  • Within ~30s: error alert with broadcast timeout copy; Place limit button enabled again (not stuck on "Placing…")
  • Repeat on /limits place + cancel an open order while offline
  • Online happy path still submits and shows success TxResultAlert with hash

@totdking — please verify on your M1 Chrome repro (offline after wallet approve). Leaving open until QA sign-off.

/cc @PlasticDigits

## Fix landed on `main` (c86553f) Trade and other on-chain submits were hanging forever when the wallet RPC / LCD poll stalled (e.g. DevTools **Offline** after approving a limit place). The shared Terra tx layer now caps **`broadcastTx`** and **`pollTx`** so React Query mutations fail and re-enable submit buttons. ### What changed - **`executeTerraContract`** / **`executeTerraContractMulti`** wrap **`wallet.broadcastTx`** (default **30s**, `VITE_TERRA_TX_BROADCAST_TIMEOUT_MS`) and **`wallet.pollTx`** (default **90s**, `VITE_TERRA_TX_POLL_TIMEOUT_MS`) via **`withPromiseTimeout`**. - Broadcast timeout copy: *"Could not broadcast the transaction. Check your connection and try again."* - Poll timeout copy: *"Transaction confirmation timed out. Check your connection and try again."* - Applies to limit place/cancel, swaps, pool txs — not only `/trade`. ### Docs / agent playbooks - [docs/frontend.md § Transaction broadcast / confirmation timeout](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/blob/main/docs/frontend.md#terra-tx-broadcast-timeout) - [`skills/AGENTS_FRONTEND_TX_BROADCAST_TIMEOUT.md`](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/blob/main/skills/AGENTS_FRONTEND_TX_BROADCAST_TIMEOUT.md) - Cross-link in [`skills/AGENTS_FRONTEND_USER_ERRORS.md`](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/blob/main/skills/AGENTS_FRONTEND_USER_ERRORS.md) and [`docs/limit-orders.md`](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/blob/main/docs/limit-orders.md) ### Verification checklist - [ ] `cd frontend-dapp && npm run test -- --run src/services/terraclassic/__tests__/transactions.test.ts src/utils/__tests__/withPromiseTimeout.test.ts` - [ ] Local: `VITE_NETWORK=local npm run dev`, Simulated Wallet, `/trade` → valid limit → DevTools **Offline** → **Place limit** → approve if prompted - [ ] Within ~30s: error alert with broadcast timeout copy; **Place limit** button enabled again (not stuck on "Placing…") - [ ] Repeat on `/limits` place + cancel an open order while offline - [ ] Online happy path still submits and shows success `TxResultAlert` with hash @totdking — please verify on your M1 Chrome repro (offline after wallet approve). Leaving open until QA sign-off. /cc @PlasticDigits
Brouie commented 2026-05-25 02:32:21 +00:00 (Migrated from gitlab.com)

verified on QA stack — fix c86553f is in main history at HEAD 5ed7429.

source: both wallet.broadcastTx and wallet.pollTx now wrapped with withPromiseTimeout in the shared broadcastTerraExecuteContracts path (terraBroadcast.ts). covers every on-chain submit: swaps, limit place/cancel, pool add/withdraw, two-step CW20 allowance flows.

caps: broadcast 30s, poll 90s, both configurable via VITE_TERRA_TX_BROADCAST_TIMEOUT_MS / VITE_TERRA_TX_POLL_TIMEOUT_MS. timeout errors pass through handleBroadcastError unchanged and surface retail copy ("Could not broadcast the transaction. Check your connection and try again." / "Transaction confirmation timed out. Check your connection and try again.").

tests: withPromiseTimeout.test.ts 2/2 PASS + transactions.test.ts 45/45 PASS = 47/47. fake-timer tests confirm never-settling broadcastTx rejects at 30s and never-settling pollTx rejects at 90s with expected messages — covers the original silent-hang behavior totdking captured.

good to close on your side @PlasticDigits

verified on QA stack — fix `c86553f` is in main history at HEAD `5ed7429`. source: both `wallet.broadcastTx` and `wallet.pollTx` now wrapped with `withPromiseTimeout` in the shared `broadcastTerraExecuteContracts` path (`terraBroadcast.ts`). covers every on-chain submit: swaps, limit place/cancel, pool add/withdraw, two-step CW20 allowance flows. caps: broadcast 30s, poll 90s, both configurable via `VITE_TERRA_TX_BROADCAST_TIMEOUT_MS` / `VITE_TERRA_TX_POLL_TIMEOUT_MS`. timeout errors pass through `handleBroadcastError` unchanged and surface retail copy ("Could not broadcast the transaction. Check your connection and try again." / "Transaction confirmation timed out. Check your connection and try again."). tests: `withPromiseTimeout.test.ts` 2/2 PASS + `transactions.test.ts` 45/45 PASS = 47/47. fake-timer tests confirm never-settling `broadcastTx` rejects at 30s and never-settling `pollTx` rejects at 90s with expected messages — covers the original silent-hang behavior totdking captured. good to close on your side @PlasticDigits
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-05-25 04:02:26 +00:00
PlasticDigits commented 2026-06-05 04:08:08 +00:00 (Migrated from gitlab.com)

mentioned in issue #305

mentioned in issue #305
PlasticDigits commented 2026-06-05 08:17:05 +00:00 (Migrated from gitlab.com)

mentioned in merge request !778

mentioned in merge request !778
PlasticDigits commented 2026-06-06 07:35:24 +00:00 (Migrated from gitlab.com)

mentioned in merge request !827

mentioned in merge request !827
PlasticDigits commented 2026-08-18 23:53:09 +00:00 (Migrated from gitlab.com)

mentioned in issue #567

mentioned in issue #567
PlasticDigits commented 2026-08-19 01:07:34 +00:00 (Migrated from gitlab.com)

mentioned in merge request !1091

mentioned in merge request !1091
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
code/cl8y-dex-terraclassic#173
No description provided.