On database error: Escape copies error and quits, additional logging

Co-authored-by: Scott Nonnenberg <scott@signal.org>
This commit is contained in:
automated-signal 2022-05-03 13:25:25 -07:00 committed by GitHub
parent 8c8a1c19f9
commit 282b43e28b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 20 deletions

View File

@ -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;

View File

@ -595,6 +595,7 @@ async function removeDB(): Promise<void> {
);
}
logger.warn('removeDB: Removing all database files');
rimraf.sync(databaseFilePath);
rimraf.sync(`${databaseFilePath}-shm`);
rimraf.sync(`${databaseFilePath}-wal`);