fix(database): improve web environment database connection handling
- Add pre-open check for web to release potentially stale OPFS handles - Unify close logic across platforms instead of skipping for web - Add proper logging for connection lifecycle operations - Remove obsolete error check for "cannot create file" during retries
This commit is contained in:
@@ -53,6 +53,17 @@ async function withMutex<T>(fn: () => Promise<T>): Promise<T> {
|
||||
async function openDatabaseWithRetry(dbName: string, maxRetries: number = 3): Promise<SQLite.SQLiteDatabase> {
|
||||
const isWeb = typeof window !== 'undefined';
|
||||
|
||||
if (isWeb) {
|
||||
try {
|
||||
const tempDb = await SQLite.openDatabaseAsync(dbName);
|
||||
await tempDb.closeAsync();
|
||||
console.log('[Database] Web: 预打开成功,已释放可能残留的句柄');
|
||||
} catch (e) {
|
||||
console.warn('[Database] Web: 预打开失败:', String(e));
|
||||
}
|
||||
await new Promise(r => setTimeout(r, 50));
|
||||
}
|
||||
|
||||
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
||||
try {
|
||||
const database = await SQLite.openDatabaseAsync(dbName);
|
||||
@@ -66,7 +77,7 @@ async function openDatabaseWithRetry(dbName: string, maxRetries: number = 3): Pr
|
||||
console.warn(`[Database] ${delay}ms 后重试...`);
|
||||
await new Promise(r => setTimeout(r, delay));
|
||||
|
||||
if (msg.includes('Invalid VFS state') || msg.includes('cannot create file')) {
|
||||
if (msg.includes('Invalid VFS state')) {
|
||||
try {
|
||||
await SQLite.deleteDatabaseAsync(dbName);
|
||||
console.warn('[Database] 已删除损坏的数据库文件');
|
||||
@@ -237,20 +248,19 @@ export const initDatabase = async (userId?: string): Promise<void> => {
|
||||
const isWeb = typeof window !== 'undefined';
|
||||
|
||||
if (db) {
|
||||
console.log(`[Database ${mutexId}] 关闭旧数据库连接...`);
|
||||
try {
|
||||
await db.closeAsync();
|
||||
console.log(`[Database ${mutexId}] 旧连接已关闭`);
|
||||
} catch (e) {
|
||||
console.warn(`[Database ${mutexId}] 关闭旧连接失败:`, e);
|
||||
}
|
||||
db = null;
|
||||
currentDbUserId = null;
|
||||
isInitialized = false;
|
||||
|
||||
if (isWeb) {
|
||||
console.log(`[Database ${mutexId}] Web:切换用户,直接置空旧连接`);
|
||||
db = null;
|
||||
currentDbUserId = null;
|
||||
isInitialized = false;
|
||||
} else {
|
||||
try {
|
||||
await db.closeAsync();
|
||||
} catch (e) {
|
||||
console.warn(`[Database ${mutexId}] 关闭旧连接失败:`, e);
|
||||
}
|
||||
db = null;
|
||||
currentDbUserId = null;
|
||||
isInitialized = false;
|
||||
await new Promise(r => setTimeout(r, 100));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,17 +295,9 @@ export const closeDatabase = async (): Promise<void> => {
|
||||
await withMutex(async () => {
|
||||
if (!db) return;
|
||||
|
||||
const isWeb = typeof window !== 'undefined';
|
||||
if (isWeb) {
|
||||
console.log('[Database] Web 环境:跳过关闭数据库,避免 OPFS 句柄冲突');
|
||||
db = null;
|
||||
currentDbUserId = null;
|
||||
isInitialized = false;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await db.closeAsync();
|
||||
console.log('[Database] 数据库已关闭');
|
||||
} catch (e) {
|
||||
console.warn('[Database] 关闭失败:', e);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user