From fb156fa7beeb190a749f152933b3f9027e6d38de Mon Sep 17 00:00:00 2001 From: Dustin <155417613+vgcman16@users.noreply.github.com> Date: Wed, 30 Oct 2024 18:06:46 -0500 Subject: [PATCH] fix: improve database initialization and error handling --- app/lib/persistence/db.ts | 21 +++++++-- app/lib/persistence/useChatHistory.ts | 66 +++++++++++++-------------- 2 files changed, 50 insertions(+), 37 deletions(-) diff --git a/app/lib/persistence/db.ts b/app/lib/persistence/db.ts index d12d7e5dc..1199ff7b8 100644 --- a/app/lib/persistence/db.ts +++ b/app/lib/persistence/db.ts @@ -5,6 +5,7 @@ import type { ChatHistoryItem } from './useChatHistory'; const logger = createScopedLogger('ChatHistory'); let dbInitAttempted = false; +let dbInitializing = false; function isBrowserEnvironment(): boolean { try { @@ -19,17 +20,19 @@ function isBrowserEnvironment(): boolean { } export async function openDatabase(): Promise { - if (dbInitAttempted) { - logger.debug('Database initialization already attempted'); + if (dbInitAttempted || dbInitializing) { + logger.debug('Database initialization already attempted or in progress'); return undefined; } - dbInitAttempted = true; + dbInitializing = true; return new Promise((resolve) => { try { if (!isBrowserEnvironment()) { logger.debug('Not in browser environment or IndexedDB not available'); + dbInitAttempted = true; + dbInitializing = false; resolve(undefined); return; } @@ -57,14 +60,20 @@ export async function openDatabase(): Promise { const transaction = db.transaction(['chats'], 'readonly'); transaction.oncomplete = () => { logger.debug('Database test successful'); + dbInitAttempted = true; + dbInitializing = false; resolve(db); }; transaction.onerror = () => { logger.error('Database test failed'); + dbInitAttempted = true; + dbInitializing = false; resolve(undefined); }; } catch (error) { logger.error('Error testing database:', error); + dbInitAttempted = true; + dbInitializing = false; resolve(undefined); } }; @@ -72,16 +81,22 @@ export async function openDatabase(): Promise { request.onerror = (event: Event) => { const error = (event.target as IDBOpenDBRequest).error; logger.error('Failed to open database:', error?.message || 'Unknown error'); + dbInitAttempted = true; + dbInitializing = false; resolve(undefined); }; request.onblocked = () => { logger.error('Database blocked'); + dbInitAttempted = true; + dbInitializing = false; resolve(undefined); }; } catch (error) { logger.error('Error initializing database:', error); + dbInitAttempted = true; + dbInitializing = false; resolve(undefined); } }); diff --git a/app/lib/persistence/useChatHistory.ts b/app/lib/persistence/useChatHistory.ts index 18bda021d..eddf17509 100644 --- a/app/lib/persistence/useChatHistory.ts +++ b/app/lib/persistence/useChatHistory.ts @@ -19,10 +19,29 @@ export interface ChatHistoryItem { // Initialize database lazily when needed let db: IDBDatabase | undefined; let dbInitialized = false; +let dbInitializing = false; export const chatId = atom(undefined); export const description = atom(undefined); +async function initializeDb() { + if (dbInitialized || dbInitializing) { + return db; + } + + dbInitializing = true; + try { + db = await openDatabase(); + dbInitialized = true; + logger.debug('Database initialized successfully'); + } catch (error) { + logger.error('Failed to initialize database:', error); + } finally { + dbInitializing = false; + } + return db; +} + export function useChatHistory() { const navigate = useNavigate(); const { id: mixedId } = useLoaderData<{ id?: string }>(); @@ -33,49 +52,28 @@ export function useChatHistory() { // Initialize database when component mounts useEffect(() => { - const initDb = async () => { + const init = async () => { try { - // Only attempt to initialize once - if (!dbInitialized) { - logger.debug('Initializing database'); - db = await openDatabase(); - dbInitialized = true; - } - - // If we have a mixedId but no database, navigate home - if (mixedId && !db) { - logger.debug('No database available, navigating home'); - navigate('/', { replace: true }); - setReady(true); - return; - } - - // If we have both mixedId and database, try to load messages - if (mixedId && db) { - try { - const storedMessages = await getMessages(db, mixedId); - if (storedMessages && storedMessages.messages.length > 0) { - setInitialMessages(storedMessages.messages); - setUrlId(storedMessages.urlId); - description.set(storedMessages.description); - chatId.set(storedMessages.id); - } else { - navigate('/', { replace: true }); - } - } catch (error) { - logger.error('Failed to load messages:', error); + const database = await initializeDb(); + + if (mixedId && database) { + const storedMessages = await getMessages(database, mixedId); + if (storedMessages && storedMessages.messages.length > 0) { + setInitialMessages(storedMessages.messages); + setUrlId(storedMessages.urlId); + description.set(storedMessages.description); + chatId.set(storedMessages.id); + } else { navigate('/', { replace: true }); } } - - setReady(true); } catch (error) { logger.error('Failed to initialize:', error); - setReady(true); } + setReady(true); }; - initDb(); + init(); }, [mixedId, navigate]); return {