Files
frontend/src/shared/api/read-failure.ts
T
codex-bot 8ce1e8e444
Frontend verify / commits (push) Skipped
Frontend verify / security (push) Successful in 9s
Frontend verify / verify (push) Failing after 7m5s
feat(investments): warn and offer retry after exhausted read retries (WealthLedger/frontend#55) (#136)
2026-11-03 09:49:08 +03:00

38 lines
1.2 KiB
TypeScript

import {
ApiErrorCode,
apiErrorCode,
isApiErrorCode,
isBrokerageAccessLoss,
} from "./problem-details";
type ReadState = { error: unknown; isError: boolean; isFetching: boolean };
type RetryableRead = ReadState & { refetch: () => Promise<unknown> };
// Automatic retries run inside one fetchAppRead call and Query's own retry is
// off, so a query in the error state has exhausted them. The state stays
// "error" while a manual retry runs, which keeps the warning in place. Access
// loss and a lost session keep their own actions and never offer a plain retry.
function isReadFailureExhausted(state: ReadState): boolean {
if (!state.isError) return false;
const code = apiErrorCode(state.error);
return !isBrokerageAccessLoss(code)
&& !isApiErrorCode(code, ApiErrorCode.Unauthorized);
}
// Retry repeats only the GET of the failed queries, never a source sync.
function readRetry(reads: RetryableRead[]) {
const failed = reads.filter(read => isReadFailureExhausted(read));
return {
exhausted: failed.length > 0,
onRetry: () => {
void Promise.allSettled(failed.map(read => read.refetch()));
},
retrying: failed.some(read => read.isFetching),
};
}
export { isReadFailureExhausted, readRetry };