2
0
mirror of https://github.com/frappe/books.git synced 2024-12-23 11:29:03 +00:00

fix: add failsafes along db connection paths

This commit is contained in:
18alantom 2021-12-10 13:36:38 +05:30
parent 415bf0e047
commit ae5cade05a
8 changed files with 77 additions and 18 deletions

View File

@ -2,7 +2,7 @@
"name": "frappe-books",
"description": "Simple book-keeping app for everyone",
"homepage": "https://frappebooks.com",
"version": "0.0.4-beta.0",
"version": "0.0.4-beta.1",
"author": {
"name": "Frappe Technologies Pvt. Ltd.",
"email": "hello@frappe.io"

View File

@ -30,9 +30,10 @@ import DatabaseSelector from './pages/DatabaseSelector';
import WindowsTitleBar from '@/components/WindowsTitleBar';
import { ipcRenderer } from 'electron';
import config from '@/config';
import { routeTo } from '@/utils';
import { IPC_MESSAGES, IPC_ACTIONS } from '@/messages';
import { connectToLocalDatabase, purgeCache } from '@/initialization';
import { routeTo, showErrorDialog } from './utils';
import { DB_CONN_FAILURE } from './messages';
export default {
name: 'App',
@ -68,15 +69,23 @@ export default {
},
async mounted() {
const lastSelectedFilePath = config.get('lastSelectedFilePath', null);
const connectionSuccess = await connectToLocalDatabase(
const { connectionSuccess, reason } = await connectToLocalDatabase(
lastSelectedFilePath
);
if (connectionSuccess) {
this.showSetupWizardOrDesk();
} else {
this.activeScreen = 'DatabaseSelector';
return;
}
if (lastSelectedFilePath) {
await showErrorDialog({
title: 'DB Connection Error',
content: `reason: ${reason}, filePath: ${lastSelectedFilePath}`,
});
}
this.activeScreen = 'DatabaseSelector';
},
methods: {
async showSetupWizardOrDesk(resetRoute = false) {

View File

@ -185,6 +185,10 @@ ipcMain.handle(IPC_ACTIONS.GET_DIALOG_RESPONSE, async (event, options) => {
return await dialog.showMessageBox(window, options);
});
ipcMain.handle(IPC_ACTIONS.SHOW_ERROR, async (event, { title, content }) => {
return await dialog.showErrorBox(title, content);
});
ipcMain.handle(IPC_ACTIONS.SAVE_HTML_AS_PDF, async (event, html, savePath) => {
return await saveHtmlAsPdf(html, savePath);
});

View File

@ -6,7 +6,7 @@ import fs from 'fs';
import models from '../models';
import regionalModelUpdates from '../models/regionalModelUpdates';
import postStart from '../server/postStart';
import { IPC_ACTIONS } from './messages';
import { DB_CONN_FAILURE, IPC_ACTIONS } from './messages';
import migrate from './migrate';
export async function createNewDatabase() {
@ -52,7 +52,7 @@ async function runRegionalModelUpdates() {
export async function connectToLocalDatabase(filePath) {
if (!filePath) {
return false;
return { connectionSuccess: false, reason: DB_CONN_FAILURE.INVALID_FILE };
}
frappe.login('Administrator');
@ -63,7 +63,7 @@ export async function connectToLocalDatabase(filePath) {
await frappe.db.connect();
} catch (error) {
console.error(error);
return false;
return { connectionSuccess: false, reason: DB_CONN_FAILURE.CANT_CONNECT };
}
try {
@ -72,8 +72,17 @@ export async function connectToLocalDatabase(filePath) {
console.error('regional model updates failed', error);
}
await migrate();
await postStart();
try {
await migrate();
await postStart();
} catch (error) {
if (!error.message.includes('SQLITE_CANTOPEN')) {
throw error;
}
console.error(error);
return { connectionSuccess: false, reason: DB_CONN_FAILURE.CANT_OPEN };
}
// set file info in config
const { companyName } = frappe.AccountingSettings;
@ -95,7 +104,7 @@ export async function connectToLocalDatabase(filePath) {
// set last selected file
config.set('lastSelectedFilePath', filePath);
return true;
return { connectionSuccess: true, reason: '' };
}
export function purgeCache(purgeAll = false) {

View File

@ -15,5 +15,12 @@ export const IPC_ACTIONS = {
GET_SAVE_FILEPATH: 'save-dialog',
GET_DIALOG_RESPONSE: 'show-message-box',
GET_PRIMARY_DISPLAY_SIZE: 'get-primary-display-size',
SAVE_HTML_AS_PDF: 'save-html-as-pdf'
SAVE_HTML_AS_PDF: 'save-html-as-pdf',
SHOW_ERROR: 'show-error',
};
export const DB_CONN_FAILURE = {
INVALID_FILE: 'invalid-file',
CANT_OPEN: 'cant-open',
CANT_CONNECT: 'cant-connect',
};

View File

@ -156,9 +156,10 @@ import fs from 'fs';
import config from '@/config';
import { DateTime } from 'luxon';
import { ipcRenderer } from 'electron';
import { IPC_ACTIONS } from '../messages';
import { DB_CONN_FAILURE, IPC_ACTIONS } from '../messages';
import { createNewDatabase, connectToLocalDatabase } from '@/initialization';
import { showErrorDialog } from '../utils';
export default {
name: 'DatabaseSelector',
@ -211,15 +212,25 @@ export default {
}
this.loadingDatabase = true;
const connectionSuccess = await connectToLocalDatabase(filePath);
const { connectionSuccess, reason } = await connectToLocalDatabase(
filePath
);
this.loadingDatabase = false;
const title = 'DB Connection Error';
if (connectionSuccess) {
this.$emit('database-connect');
} else if (reason === DB_CONN_FAILURE.CANT_OPEN) {
await showErrorDialog({
title,
content: `Can't open database file: ${filePath}, please create a new file.`,
});
} else {
alert(
frappe._('Please select an existing database or create a new one.')
);
await showErrorDialog({
title,
content: `Please select an existing database or create a new one. reason: ${reason}, filePath: ${filePath}`,
});
}
},
getFileLastModified(filePath) {

View File

@ -78,6 +78,7 @@ import {
getErrorMessage,
handleErrorWithDialog,
showMessageDialog,
showErrorDialog,
} from '@/utils';
export default {
@ -151,10 +152,18 @@ export default {
purgeCache();
const connectionSuccess = await connectToLocalDatabase(filePath);
const { connectionSuccess, reason } = await connectToLocalDatabase(
filePath
);
if (connectionSuccess) {
await setupCompany(this.doc);
this.$emit('setup-complete');
} else {
await showErrorDialog({
title: 'DB Connection Error',
content: `reason: ${reason}, filePath: ${filePath}`,
});
}
},
},

View File

@ -27,6 +27,16 @@ export async function showMessageDialog({
}
}
export async function showErrorDialog({ title, content }) {
// To be used for show stopper errors
title = title ?? 'Error';
content =
content ??
'Something has gone terribly wrong. Please check the console and raise an issue.';
await ipcRenderer.invoke(IPC_ACTIONS.SHOW_ERROR, { title, content });
}
export function deleteDocWithPrompt(doc) {
return new Promise((resolve) => {
showMessageDialog({