Repository navigation
fix(api): harden API client with timeouts, abort, safe GET retries - #1568
Conversation
|
@abdulraheemabdullahi30-tech Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
abaf9a8 to
bf700f0
Compare
Strips the payload this branch picked up (deleted api.js, truncated eslint.config.js, unhooked package.json). No functional change to the branch's own work.
aaf2dd6 to
fce235d
Compare
fce235d to
a1d8952
Compare
a1d8952 to
0b1a3a6
Compare
|
Hi @abdulraheemabdullahi30-tech, thanks for the PR. We can't merge it yet: it adds these two lines to These entries are a known indicator of a malware campaign that infects developer machines and auto-pushes hidden code to their repositories. The malware adds them to hide its own helper scripts. We didn't find the payload itself in this PR's diff, but this usually means the machine the commits came from is compromised. What to do before we can merge this PR
Thanks for your contribution, and sorry for the hassle. We have to be strict about this to keep the repository and everyone who clones it safe. |
|
@1nonlypiece — this PR is ready for another review. I resolved the merge conflicts with the main branch (pushed c955d36). |
cd5e1eb to
4b761ef
Compare
4b761ef to
a813ddf
Compare
a813ddf to
0ffc37f
Compare
0ffc37f to
f0c5f3e
Compare
f0c5f3e to
5d40107
Compare
5d40107 to
d0bd09f
Compare
d0bd09f to
b8b6a95
Compare
b8b6a95 to
6e40242
Compare
Overview
This PR hardens
src/services/api.tsso a slow or misbehaving API can no longer hang the UI or feedundefinedinto pages. It adds per-request timeouts,AbortSignalsupport, bounded retry with backoff for idempotent GETs only, drops the unnecessarycontent-typeheader on GETs (avoiding a CORS preflight), and validates the{ data }envelope at runtime.vaultServicelist/get/activity functions now accept an optional{ signal }, andVaultspasses a signal that is aborted on unmount.Related Issue
Changes
🛡️ API request core (
src/services/api.ts)request<T>(path, { method, body, signal, timeoutMs = 10_000, retries })AbortSignal.any, with a small manual combiner fallback for older Safari.content-type: application/jsonwhen a body is present, so GETs stay simple requests and skip theOPTIONSpreflight.502/503/504and429(honoringRetry-Aftercapped at 5 s), with exponential backoff and jitter. POSTs are never retried.datakey, otherwise throwsApiError('Malformed API response', status, 'invalid_response').ApiErrorgains acodefield (network|timeout|aborted|http|invalid_response); error messages composeerror+detailswithout ever including request bodies.🔌 Signal plumbing (
src/services/vaultService.ts)apiListVaults,apiGetVault, and the activity fetcher accept an optional{ signal }and forward it torequest.🖥️ Page cleanup (
src/pages/Vaults.tsx)AbortControllerin the effect, passes itssignalto the vault service, and aborts on cleanup so no state update happens after unmount.Verification Results
ApiErrorcodetimeoutaftertimeoutMs(default 10 s)code: 'timeout'aborted; no state update after unmount inVaultscode: 'aborted';Vaultsaborts on cleanupcontent-typeheader; POSTs dodata-less body rejects with codeinvalid_responseinstead of returningundefineddataNotes
Transactions.tsxsignal plumbing is out of scope for this change set and will follow in a separate PR.Closes #1506