Улучшена логика проверки сетевого статуса в функции initOfflineMode, добавлены дополнительные проверки для определения оффлайн-режима. Обновлена обработка ошибок при создании заметок, добавлена логика для обработки сетевых ошибок и локального создания заметок. Оптимизирована функция checkNetworkStatus для более точного определения состояния сети с учетом таймаутов и различных типов ошибок.
This commit is contained in:
parent
2c23044ea4
commit
351ba7eb03
@ -239,10 +239,62 @@ export const offlineNotesApi = {
|
|||||||
store.dispatch(addNote(noteWithSyncStatus));
|
store.dispatch(addNote(noteWithSyncStatus));
|
||||||
|
|
||||||
return noteWithSyncStatus;
|
return noteWithSyncStatus;
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
console.error("Error creating note, falling back to local:", error);
|
// Проверяем, является ли это сетевой ошибкой
|
||||||
// Fallback на локальное создание
|
const isNetworkError =
|
||||||
return offlineNotesApi.create(note);
|
!error.response &&
|
||||||
|
(error.code === 'ERR_NETWORK' ||
|
||||||
|
error.message === 'Network Error' ||
|
||||||
|
error.message?.includes('ERR_INTERNET_DISCONNECTED') ||
|
||||||
|
error.message?.includes('Failed to fetch'));
|
||||||
|
|
||||||
|
if (isNetworkError) {
|
||||||
|
console.error("Network error creating note, falling back to local:", error);
|
||||||
|
|
||||||
|
// Принудительно обновляем статус сети при ошибке
|
||||||
|
lastNetworkCheck = { time: Date.now(), status: false };
|
||||||
|
store.dispatch(setOfflineMode(true));
|
||||||
|
|
||||||
|
// Fallback на локальное создание напрямую, без рекурсии
|
||||||
|
console.log("[Offline] Creating note locally after network error");
|
||||||
|
|
||||||
|
const tempId = generateTempId();
|
||||||
|
const now = new Date().toISOString();
|
||||||
|
const newNote: Note = {
|
||||||
|
...note,
|
||||||
|
id: tempId,
|
||||||
|
user_id: userId || 0,
|
||||||
|
created_at: now,
|
||||||
|
updated_at: now,
|
||||||
|
is_pinned: 0,
|
||||||
|
is_archived: 0,
|
||||||
|
images: [],
|
||||||
|
files: [],
|
||||||
|
syncStatus: "pending",
|
||||||
|
};
|
||||||
|
|
||||||
|
// Сохраняем в IndexedDB
|
||||||
|
await dbManager.saveNote(newNote);
|
||||||
|
|
||||||
|
// Добавляем в очередь синхронизации
|
||||||
|
await dbManager.addToSyncQueue({
|
||||||
|
type: "create",
|
||||||
|
noteId: tempId,
|
||||||
|
data: note,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
retries: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Обновляем UI
|
||||||
|
store.dispatch(addNote(newNote));
|
||||||
|
await updatePendingSyncCount();
|
||||||
|
|
||||||
|
return newNote;
|
||||||
|
} else {
|
||||||
|
// Если это не сетевая ошибка, пробрасываем её дальше
|
||||||
|
console.error("Error creating note (not a network error):", error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
24
src/main.tsx
24
src/main.tsx
@ -24,7 +24,29 @@ async function initOfflineMode() {
|
|||||||
console.log('[Init] IndexedDB initialized');
|
console.log('[Init] IndexedDB initialized');
|
||||||
|
|
||||||
// Проверка состояния сети
|
// Проверка состояния сети
|
||||||
const isOnline = await checkNetworkStatus();
|
// Сначала проверяем navigator.onLine для быстрой проверки
|
||||||
|
let isOnline: boolean = navigator.onLine;
|
||||||
|
|
||||||
|
// Если navigator.onLine = false, точно оффлайн (не нужно делать fetch)
|
||||||
|
if (!navigator.onLine) {
|
||||||
|
isOnline = false;
|
||||||
|
} else {
|
||||||
|
// Если navigator.onLine = true, делаем дополнительную проверку через fetch
|
||||||
|
try {
|
||||||
|
isOnline = await checkNetworkStatus();
|
||||||
|
} catch (error) {
|
||||||
|
// Если проверка сети упала с ошибкой, скорее всего мы оффлайн
|
||||||
|
console.warn('[Init] Network status check failed, assuming offline:', error);
|
||||||
|
isOnline = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Финальная проверка: если navigator.onLine = false, точно оффлайн
|
||||||
|
// Это важно, так как navigator.onLine может обновиться во время проверки
|
||||||
|
if (!navigator.onLine) {
|
||||||
|
isOnline = false;
|
||||||
|
}
|
||||||
|
|
||||||
store.dispatch(setOfflineMode(!isOnline));
|
store.dispatch(setOfflineMode(!isOnline));
|
||||||
console.log(`[Init] Network status: ${isOnline ? 'online' : 'offline'}`);
|
console.log(`[Init] Network status: ${isOnline ? 'online' : 'offline'}`);
|
||||||
|
|
||||||
|
|||||||
@ -47,6 +47,7 @@ export async function checkNetworkStatus(): Promise<boolean> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Дополнительная проверка через fetch с коротким таймаутом
|
// Дополнительная проверка через fetch с коротким таймаутом
|
||||||
|
// Используем короткий таймаут для быстрого определения оффлайна
|
||||||
try {
|
try {
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
const timeoutId = setTimeout(() => controller.abort(), 2000);
|
const timeoutId = setTimeout(() => controller.abort(), 2000);
|
||||||
@ -61,9 +62,36 @@ export async function checkNetworkStatus(): Promise<boolean> {
|
|||||||
|
|
||||||
clearTimeout(timeoutId);
|
clearTimeout(timeoutId);
|
||||||
return response.ok;
|
return response.ok;
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
// Если запрос не удался, но navigator.onLine = true, считаем что онлайн
|
// Если запрос не удался, проверяем тип ошибки
|
||||||
// (возможно, просто таймаут или другая проблема)
|
const isAbortError = error.name === 'AbortError'; // Таймаут
|
||||||
|
const isNetworkError =
|
||||||
|
error.message === 'Failed to fetch' ||
|
||||||
|
error.message?.includes('NetworkError') ||
|
||||||
|
error.message?.includes('ERR_INTERNET_DISCONNECTED') ||
|
||||||
|
error.message?.includes('ERR_NETWORK') ||
|
||||||
|
error.message?.includes('network request failed');
|
||||||
|
|
||||||
|
// Если это явная сетевая ошибка (не таймаут), точно оффлайн
|
||||||
|
if (isNetworkError && !isAbortError) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Если это таймаут, проверяем navigator.onLine
|
||||||
|
// Таймаут может быть как из-за оффлайна, так и из-за медленного соединения
|
||||||
|
if (isAbortError) {
|
||||||
|
// Если navigator.onLine = false, точно оффлайн
|
||||||
|
if (!navigator.onLine) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Если navigator.onLine = true, но таймаут - возможно медленное соединение
|
||||||
|
// Но для безопасности считаем оффлайном, так как запрос не прошел
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Если это не сетевая ошибка и не таймаут (например, CORS или другая проблема),
|
||||||
|
// но navigator.onLine = true, считаем что онлайн
|
||||||
|
// (возможно, просто другая проблема, но сеть есть)
|
||||||
return navigator.onLine;
|
return navigator.onLine;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user