Skip to content

fix: timeout hung stream fetches, backoff SSE reconnects, testable polling, UTC dates - #1139

Merged
ogazboiz merged 1 commit into
LabsCrypt:mainfrom
davidmaronio:fix/issues-1040-1041-1042-1043
Jul 30, 2026
Merged

fix: timeout hung stream fetches, backoff SSE reconnects, testable polling, UTC dates#1139
ogazboiz merged 1 commit into
LabsCrypt:mainfrom
davidmaronio:fix/issues-1040-1041-1042-1043

Conversation

@davidmaronio

Copy link
Copy Markdown
Contributor

#1042 — lib/api/streams.ts has no timeout on its fetch calls

Added a shared fetchWithTimeout wrapper in lib/api/_shared.ts (AbortController-based, configurable timeoutMs, default 10s) and switched fetchIncomingStreams to use it instead of a bare fetch. A stalled backend now rejects with a FetchTimeoutError carrying a clear message ("Request timed out after Xms") instead of leaving the query pending forever; this message already surfaces in the incoming-streams UI via the existing query.error.message error path.

#1041 — useStreamEvents.ts has no exponential backoff after repeated reconnect failures

Reworked the reconnect scheduling so the next (doubled, capped) delay is computed up front, before the retry timer is scheduled, so the backoff reliably grows across consecutive SSE failures instead of only doubling lazily inside the timeout callback. The delay still resets to its initial value on a successful connection.

#1040 — useIncomingStreams.ts refetch interval is hardcoded and cannot be disabled for tests

useIncomingStreams now accepts an optional second options argument with refetchInterval. Default behavior is unchanged (no polling); tests (or future call sites) can now pass an explicit interval instead of needing to globally mock timers.

#1043 — lib/dashboard.ts date formatting uses the browser's local timezone with no explicit UTC handling

Extracted the stream date formatting into a documented formatStreamDateUtc helper with a comment explaining the strategy: always display in UTC so two viewers in different timezones see the same date for the same stream. The one date-formatting call site in this file now goes through it.

Also fixes two small pre-existing bugs uncovered while touching these files (both silently broke tsc/lint/vitest for the files involved, unrelated to the behavior above, no behavior change):

  • dashboard.ts: a mismatched brace in fetchStreams's try/catch block.
  • useIncomingStreams.test.ts contained JSX but had a .ts extension; renamed to .tsx.

Test plan

  • npx vitest run — all tests pass except one pre-existing, unrelated failure (useWithdrawIncomingStream > invalidates incomingStreamsQueryKey(publicKey) on success, which uses real timers against a slow exponential poll and was already broken before this PR, just previously masked by the .ts/.tsx transform bug above)
  • npx eslint clean on all changed files
  • New tests: hung-fetch timeout in streams.test.ts, growing/capped/reset backoff delay in useStreamEvents.test.tsx, default vs. overridden refetchInterval in useIncomingStreams.test.tsx, UTC date stability in dashboard.test.ts

Closes #1040
Closes #1041
Closes #1042
Closes #1043

…llow test overrides, format dates in UTC

- lib/api/streams.ts and lib/api/_shared.ts: add a shared fetchWithTimeout
  wrapper (AbortController-based, configurable) so a stalled backend surfaces
  a clear timeout error instead of hanging the UI forever.
- hooks/useStreamEvents.ts: precompute the capped, doubled reconnect delay
  before scheduling the retry so exponential backoff keeps growing across
  consecutive SSE failures and resets on a successful connection.
- hooks/useIncomingStreams.ts: accept an optional refetchInterval override so
  tests can disable/control polling instead of needing global timer mocks;
  default behavior (no polling) is unchanged.
- lib/dashboard.ts: document and apply a consistent UTC date-formatting
  strategy via formatStreamDateUtc so a stream's displayed date/duration no
  longer depends on the viewer's local timezone.

Also fixes two pre-existing, unrelated bugs in files these changes required
touching, both of which were silently breaking tsc/lint/vitest for those
files: a mismatched brace in dashboard.ts's fetchStreams try/catch, and
useIncomingStreams.test.ts containing JSX under a .ts extension (renamed to
.tsx). Neither changes behavior.

Closes LabsCrypt#1040
Closes LabsCrypt#1041
Closes LabsCrypt#1042
Closes LabsCrypt#1043
@ogazboiz
ogazboiz merged commit 4beb172 into LabsCrypt:main Jul 30, 2026
6 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment