fix and update
This commit is contained in:
@@ -160,7 +160,9 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
setHasStoredSession(true);
|
||||
clearPinLock();
|
||||
if (auth.pinVerified !== false) {
|
||||
void syncFedcmSession(auth.accessToken);
|
||||
window.setTimeout(() => {
|
||||
void syncFedcmSession(auth.accessToken);
|
||||
}, 300);
|
||||
}
|
||||
},
|
||||
[clearPinLock]
|
||||
|
||||
@@ -506,7 +506,7 @@ export async function refreshAuthSession(): Promise<RefreshSessionResponse> {
|
||||
throw new ApiError('Refresh token отсутствует', 401, 'NO_REFRESH');
|
||||
}
|
||||
|
||||
const response = await fetch(`${getApiUrl()}/auth/refresh`, {
|
||||
const response = await fetchWithGatewayRetry(`${getApiUrl()}/auth/refresh`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ refreshToken, sessionId: sessionId ?? undefined })
|
||||
@@ -522,7 +522,7 @@ export async function refreshAuthSession(): Promise<RefreshSessionResponse> {
|
||||
export async function syncFedcmSession(accessToken: string) {
|
||||
if (typeof window === 'undefined' || !accessToken.trim()) return;
|
||||
try {
|
||||
await fetch(`${getApiUrl()}/fedcm/session/sync`, {
|
||||
await fetchWithGatewayRetry(`${getApiUrl()}/fedcm/session/sync`, {
|
||||
method: 'POST',
|
||||
headers: { Authorization: `Bearer ${accessToken.trim()}` },
|
||||
credentials: 'include'
|
||||
@@ -624,6 +624,36 @@ export function buildSystemSettingPayload(setting: Pick<SystemSetting, 'key' | '
|
||||
};
|
||||
}
|
||||
|
||||
const GATEWAY_RETRY_STATUS = new Set([502, 503, 504]);
|
||||
const GATEWAY_RETRY_ATTEMPTS = 3;
|
||||
|
||||
function sleep(ms: number): Promise<void> {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
/** Повтор при кратковременном 502/503/504 (nginx не достучался до api-gateway после перезапуска). */
|
||||
async function fetchWithGatewayRetry(url: string, init: RequestInit): Promise<Response> {
|
||||
let lastNetworkError: unknown;
|
||||
for (let attempt = 0; attempt < GATEWAY_RETRY_ATTEMPTS; attempt++) {
|
||||
try {
|
||||
const response = await fetch(url, init);
|
||||
if (GATEWAY_RETRY_STATUS.has(response.status) && attempt + 1 < GATEWAY_RETRY_ATTEMPTS) {
|
||||
await sleep(250 * (attempt + 1));
|
||||
continue;
|
||||
}
|
||||
return response;
|
||||
} catch (error) {
|
||||
lastNetworkError = error;
|
||||
if (attempt + 1 < GATEWAY_RETRY_ATTEMPTS) {
|
||||
await sleep(250 * (attempt + 1));
|
||||
continue;
|
||||
}
|
||||
throw mapFetchError(error);
|
||||
}
|
||||
}
|
||||
throw mapFetchError(lastNetworkError);
|
||||
}
|
||||
|
||||
export async function apiFetch<T>(path: string, options: RequestInit = {}, token?: string | null, allowRetry = true): Promise<T> {
|
||||
const resolvedToken = token ?? (typeof window !== 'undefined' ? window.localStorage.getItem(AUTH_TOKEN_KEY) : null);
|
||||
const method = (options.method ?? 'GET').toUpperCase();
|
||||
@@ -638,11 +668,14 @@ export async function apiFetch<T>(path: string, options: RequestInit = {}, token
|
||||
|
||||
let response: Response;
|
||||
try {
|
||||
response = await fetch(`${getApiUrl()}${path}`, {
|
||||
response = await fetchWithGatewayRetry(`${getApiUrl()}${path}`, {
|
||||
...options,
|
||||
headers
|
||||
});
|
||||
} catch (error) {
|
||||
if (error instanceof ApiError) {
|
||||
throw error;
|
||||
}
|
||||
throw mapFetchError(error);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user