Улучшена логика проверки сетевого статуса в функции initOfflineMode, добавлены дополнительные проверки для определения оффлайн-режима. Обновлена обработка ошибок при создании заметок, добавлена логика для обработки сетевых ошибок и локального создания заметок. Оптимизирована функция checkNetworkStatus для более точного определения состояния сети с учетом таймаутов и различных типов ошибок.
This commit is contained in:
parent
2c23044ea4
commit
351ba7eb03
@ -239,10 +239,62 @@ export const offlineNotesApi = {
|
||||
store.dispatch(addNote(noteWithSyncStatus));
|
||||
|
||||
return noteWithSyncStatus;
|
||||
} catch (error) {
|
||||
console.error("Error creating note, falling back to local:", error);
|
||||
// Fallback на локальное создание
|
||||
return offlineNotesApi.create(note);
|
||||
} catch (error: any) {
|
||||
// Проверяем, является ли это сетевой ошибкой
|
||||
const isNetworkError =
|
||||
!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');
|
||||
|
||||
// Проверка состояния сети
|
||||
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));
|
||||
console.log(`[Init] Network status: ${isOnline ? 'online' : 'offline'}`);
|
||||
|
||||
|
||||
@ -47,6 +47,7 @@ export async function checkNetworkStatus(): Promise<boolean> {
|
||||
}
|
||||
|
||||
// Дополнительная проверка через fetch с коротким таймаутом
|
||||
// Используем короткий таймаут для быстрого определения оффлайна
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 2000);
|
||||
@ -61,9 +62,36 @@ export async function checkNetworkStatus(): Promise<boolean> {
|
||||
|
||||
clearTimeout(timeoutId);
|
||||
return response.ok;
|
||||
} catch (error) {
|
||||
// Если запрос не удался, но navigator.onLine = true, считаем что онлайн
|
||||
// (возможно, просто таймаут или другая проблема)
|
||||
} catch (error: any) {
|
||||
// Если запрос не удался, проверяем тип ошибки
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user