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:
parent
415bf0e047
commit
ae5cade05a
@ -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"
|
||||
|
17
src/App.vue
17
src/App.vue
@ -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) {
|
||||
|
@ -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);
|
||||
});
|
||||
|
@ -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) {
|
||||
|
@ -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',
|
||||
};
|
||||
|
@ -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) {
|
||||
|
@ -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}`,
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
|
10
src/utils.js
10
src/utils.js
@ -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({
|
||||
|
Loading…
Reference in New Issue
Block a user