fix: 修复打包后应用无法启动(sql.js WASM 不含 FTS5 模块)

根因分析:
- sql.js 默认 WASM 构建不包含 FTS5 全文搜索扩展
- initDatabase() 中 CREATE VIRTUAL TABLE USING fts5 直接抛异常
- app.whenReady() 链没有 .catch(),错误被静默吞掉
- 结果:进程启动但窗口永远不显示(用户看到双击没反应)

修复内容:
1. main.ts: 添加 app.whenReady().catch() 错误处理,失败时弹出错误对话框
2. main.ts: 添加全局 uncaughtException/unhandledRejection 处理,写入 startup-error.log
3. sqlite.ts: FTS5 虚拟表创建改为可选,缺失时自动降级为 LIKE 搜索
4. sqlite.ts: 所有 FTS5 同步操作(save/delete/clear)加 _hasFTS5 守卫
This commit is contained in:
thzxx
2026-04-18 07:42:54 +08:00
parent 4518929a4c
commit 95153e9171
2 changed files with 69 additions and 17 deletions
+28 -1
View File
@@ -2,7 +2,7 @@
* Metona Ollama Desktop - 主进程入口
*/
import { app, BrowserWindow } from 'electron';
import { app, BrowserWindow, dialog } from 'electron';
import * as path from 'path';
import * as fs from 'fs';
import { setupIPC } from './ipc.js';
@@ -11,6 +11,23 @@ import { createMenu } from './menu.js';
import { showNotification } from './utils.js';
import { ensureWorkspaceDir, killAllProcesses } from './workspace.js';
// ── 全局错误处理:写入文件 + 弹窗提示 ──
const ERROR_LOG = path.join(app.getPath('userData'), 'startup-error.log');
function logStartupError(phase: string, err: unknown): void {
const msg = `[${new Date().toISOString()}] ${phase}: ${err instanceof Error ? err.stack || err.message : String(err)}\n`;
try { fs.appendFileSync(ERROR_LOG, msg); } catch { /* ignore */ }
console.error(msg);
}
process.on('uncaughtException', (err) => {
logStartupError('uncaughtException', err);
});
process.on('unhandledRejection', (err) => {
logStartupError('unhandledRejection', err);
});
const APP_NAME = 'Metona Ollama';
const ICON_PATH = path.join(__dirname, '..', '..', 'assets', 'icons', 'llama.png');
const ICO_PATH = path.join(__dirname, '..', '..', 'assets', 'icons', 'llama.ico');
@@ -157,6 +174,16 @@ app.whenReady().then(async () => {
mainWindow.show();
}
});
}).catch((err) => {
logStartupError('app.whenReady', err);
// 弹出错误对话框,让用户知道发生了什么
try {
dialog.showErrorBox('Metona Ollama 启动失败',
`应用初始化出错,请检查以下信息:\n\n${err instanceof Error ? err.message : String(err)}\n\n错误日志:${ERROR_LOG}`);
} catch {
// dialog 也可能失败(app 未完全初始化)
}
app.quit();
});
app.on('window-all-closed', () => {