Skip to content

Centralize and retry-handle session-aware fetches in lib/client/apiClient.ts (401 -> refresh -> retry) #484

@Baskarayelu

Description

@Baskarayelu

📋 Description

lib/client/apiClient.ts is the shared client-side fetch wrapper, but several places call fetch directly (e.g. lib/hooks/useFormAction.ts) and there is a separate session handler at lib/client/sessionHandler.ts plus a refresh flow exercised in tests/session/session-refresh.test.ts. On a 401 (expired iron-session), there is no consistent "attempt refresh, then retry once" behavior, so users get spurious failures mid-flow.

Why this matters: wallet sessions expire. Without a single client that transparently refreshes on 401 and retries once, every form has to reinvent it — and most won't, so users hit dead ends during a send or bill payment.

🎯 Requirements & Context

Functional requirements

  • Make apiClient the single path for authenticated client fetches; on 401, attempt a session refresh via sessionHandler, then retry the original request once.
  • If refresh fails, surface the session-expiry path used by useSessionExpiry / SessionExpiryNotification instead of a generic error.
  • Avoid infinite retry loops (retry at most once).
  • Add a Vitest test covering 401→refresh→retry success and refresh-failure paths (consistent with tests/session).

Context & constraints

  • Security: never retry after a failed refresh; never leak tokens to logs (lib/logger.ts).
  • Keep the existing public function signatures backward compatible.

🛠️ Suggested Execution

git checkout -b refactor/apiclient-401-refresh-retry
  • Implement refresh-retry, route callers through it, add tests + TSDoc.
npm run lint
npx tsc --noEmit
npm run test:coverage
  • Edge cases: 401 then refresh success, 401 then refresh failure, 403 (must not retry), concurrent 401s (single refresh), abort during refresh.

Example commit message

refactor(api-client): transparent 401 -> refresh -> retry-once

Centralizes authenticated fetches, refreshes the session on 401 and
retries once, falling back to the session-expiry path on failure.

✅ Acceptance Criteria & Guidelines

Requirement Target
401 -> refresh -> retry-once implemented Required
No infinite retry; 403 not retried Required
Falls back to session-expiry UX Required
Test coverage of refresh paths ≥ 90%
No token leakage in logs Required
Lint + typecheck clean Required
Timeframe 96 hours from assignment

💬 Community & Support

Join the RemitWise contributor community on Discord: https://discord.gg/CtQuPZFMA

Comment to claim before starting. 🚀

Metadata

Metadata

Assignees

Type

No fields configured for Task.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions