diff --git a/app/main.ts b/app/main.ts index 518a4c98f..2bed7f977 100644 --- a/app/main.ts +++ b/app/main.ts @@ -1287,6 +1287,21 @@ function showPermissionsPopupWindow(forCalling: boolean, forCamera: boolean) { }); } +const runSQLCorruptionHandler = async () => { + // This is a glorified event handler. Normally, this promise never resolves, + // but if there is a corruption error triggered by any query that we run + // against the database - the promise will resolve and we will call + // `onDatabaseError`. + const error = await sql.whenCorrupted(); + + getLogger().error( + 'Detected sql corruption in main process. ' + + `Restarting the application immediately. Error: ${error.message}` + ); + + await onDatabaseError(error.stack || error.message); +}; + async function initializeSQL( userDataPath: string ): Promise<{ ok: true; error: undefined } | { ok: false; error: Error }> { @@ -1331,6 +1346,9 @@ async function initializeSQL( sqlInitTimeEnd = Date.now(); } + // Only if we've initialized things successfully do we set up the corruption handler + runSQLCorruptionHandler(); + return { ok: true, error: undefined }; } @@ -1346,44 +1364,32 @@ const onDatabaseError = async (error: string) => { const buttonIndex = dialog.showMessageBoxSync({ buttons: [ - getLocale().i18n('copyErrorAndQuit'), getLocale().i18n('deleteAndRestart'), + getLocale().i18n('copyErrorAndQuit'), ], - defaultId: 0, + defaultId: 1, + cancelId: 1, detail: redactAll(error), message: getLocale().i18n('databaseError'), noLink: true, type: 'error', }); - if (buttonIndex === 0) { + if (buttonIndex === 1) { clipboard.writeText(`Database startup error:\n\n${redactAll(error)}`); } else { await sql.removeDB(); userConfig.remove(); + getLogger().error( + 'onDatabaseError: Requesting immediate restart after quit' + ); app.relaunch(); } + getLogger().error('onDatabaseError: Quitting application'); app.exit(1); }; -const runSQLCorruptionHandler = async () => { - // This is a glorified event handler. Normally, this promise never resolves, - // but if there is a corruption error triggered by any query that we run - // against the database - the promise will resolve and we will call - // `onDatabaseError`. - const error = await sql.whenCorrupted(); - - getLogger().error( - 'Detected sql corruption in main process. ' + - `Restarting the application immediately. Error: ${error.message}` - ); - - await onDatabaseError(error.stack || error.message); -}; - -runSQLCorruptionHandler(); - let sqlInitPromise: | Promise<{ ok: true; error: undefined } | { ok: false; error: Error }> | undefined; diff --git a/ts/sql/Server.ts b/ts/sql/Server.ts index 6d8a7e843..e7c6febbf 100644 --- a/ts/sql/Server.ts +++ b/ts/sql/Server.ts @@ -595,6 +595,7 @@ async function removeDB(): Promise { ); } + logger.warn('removeDB: Removing all database files'); rimraf.sync(databaseFilePath); rimraf.sync(`${databaseFilePath}-shm`); rimraf.sync(`${databaseFilePath}-wal`);