📋 Description
lib/hooks/useFormAction.ts is the shared form-submission hook used across server-action-style forms. Today it does a single fetch(url, { method, body: formData }) inside startTransition and collapses every failure into a static "Network error. Please try again." string. There is no timeout, no abort on unmount, and no retry for transient failures.
This issue hardens the hook with an AbortController-based timeout, cancel-on-unmount, and a bounded retry for idempotent methods, while keeping the existing [state, formAction, isPending] tuple API.
Why this matters: a long-hanging POST currently leaves the form stuck in the pending state forever, and a fast unmount leaks a pending state update — both are real UX and React-warning hazards.
🎯 Requirements & Context
Functional requirements
Context & constraints
- Preserve the exact
[state, formAction, isPending] as const return shape — many forms depend on it.
- Keep
ActionState typing from lib/auth/middleware.
- Stay framework-native (
useTransition); do not add a data-fetching dependency.
🛠️ Suggested Execution
git checkout -b feature/use-form-action-retry-timeout
- Implement abort/timeout/retry; add TSDoc with
@example.
- Add vitest unit tests covering: success, timeout fires abort, unmount cancels (no state update), retry stops after the bound, non-retryable methods never retry.
- Edge cases: empty body, server returns non-JSON, repeated rapid submits.
npx vitest run
npx tsc --noEmit && npm run lint
feat(hooks): add abortable timeout + bounded retry to useFormAction
✅ Acceptance Criteria & Guidelines
| Requirement |
Target |
| Public tuple API unchanged |
Required |
| Abort-on-unmount + timeout |
Required |
| Retry bounded and method-aware |
Required |
| Test coverage of new branches |
≥ 90% |
tsc --noEmit, lint clean |
Required |
| Timeframe |
96 hours from assignment |
💬 Community & Support
Join the RemitWise contributor community on Discord: https://discord.gg/CtQuPZFMA
Please comment to claim the issue and ask questions in the channel. 🚀
📋 Description
lib/hooks/useFormAction.tsis the shared form-submission hook used across server-action-style forms. Today it does a singlefetch(url, { method, body: formData })insidestartTransitionand collapses every failure into a static"Network error. Please try again."string. There is no timeout, no abort on unmount, and no retry for transient failures.This issue hardens the hook with an
AbortController-based timeout, cancel-on-unmount, and a bounded retry for idempotent methods, while keeping the existing[state, formAction, isPending]tuple API.🎯 Requirements & Context
Functional requirements
timeoutMs(default e.g. 15000) usingAbortControllerinuseFormAction.ts.setStateafter unmount.state.error.Context & constraints
[state, formAction, isPending] as constreturn shape — many forms depend on it.ActionStatetyping fromlib/auth/middleware.useTransition); do not add a data-fetching dependency.🛠️ Suggested Execution
@example.npx vitest run npx tsc --noEmit && npm run lint✅ Acceptance Criteria & Guidelines
tsc --noEmit,lintclean💬 Community & Support
Join the RemitWise contributor community on Discord: https://discord.gg/CtQuPZFMA
Please comment to claim the issue and ask questions in the channel. 🚀