mirror of
https://github.com/frappe/books.git
synced 2024-11-08 14:50:56 +00:00
fix: capture patch fail errors
- dont notify user - catch uncaught promise in migration - prevent unable to acquire conn error
This commit is contained in:
parent
b460e96c97
commit
754a1a8e50
@ -3,11 +3,7 @@ import { DatabaseError } from 'fyo/utils/errors';
|
||||
import path from 'path';
|
||||
import { DatabaseDemuxBase, DatabaseMethod } from 'utils/db/types';
|
||||
import { getSchemas } from '../../schemas';
|
||||
import {
|
||||
databaseMethodSet,
|
||||
emitMainProcessError,
|
||||
unlinkIfExists
|
||||
} from '../helpers';
|
||||
import { checkFileAccess, databaseMethodSet, unlinkIfExists } from '../helpers';
|
||||
import patches from '../patches';
|
||||
import { BespokeQueries } from './bespoke';
|
||||
import DatabaseCore from './core';
|
||||
@ -64,8 +60,8 @@ export class DatabaseManager extends DatabaseDemuxBase {
|
||||
|
||||
try {
|
||||
await this.#runPatchesAndMigrate();
|
||||
} catch (err) {
|
||||
this.#handleFailedMigration(err, dbPath, copyPath);
|
||||
} catch (error) {
|
||||
await this.#handleFailedMigration(error, dbPath, copyPath);
|
||||
} finally {
|
||||
await unlinkIfExists(copyPath);
|
||||
}
|
||||
@ -78,8 +74,8 @@ export class DatabaseManager extends DatabaseDemuxBase {
|
||||
) {
|
||||
await this.db!.close();
|
||||
|
||||
if (copyPath) {
|
||||
await this.#restoreDbCopy(dbPath, copyPath);
|
||||
if (copyPath && (await checkFileAccess(copyPath))) {
|
||||
await fs.copyFile(copyPath, dbPath);
|
||||
}
|
||||
|
||||
if (error instanceof Error) {
|
||||
@ -89,14 +85,6 @@ export class DatabaseManager extends DatabaseDemuxBase {
|
||||
throw error;
|
||||
}
|
||||
|
||||
async #restoreDbCopy(dbPath: string, copyPath: string) {
|
||||
try {
|
||||
await fs.copyFile(copyPath!, dbPath);
|
||||
} catch (err) {
|
||||
emitMainProcessError(err);
|
||||
}
|
||||
}
|
||||
|
||||
async #runPatchesAndMigrate() {
|
||||
const patchesToExecute = await this.#getPatchesToExecute();
|
||||
|
||||
@ -152,8 +140,8 @@ export class DatabaseManager extends DatabaseDemuxBase {
|
||||
throw new DatabaseError(`invalid bespoke db function ${method}`);
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
const queryFunction: BespokeFunction = BespokeQueries[method];
|
||||
const queryFunction: BespokeFunction =
|
||||
BespokeQueries[method as keyof BespokeFunction];
|
||||
return await queryFunction(this.db!, ...args);
|
||||
}
|
||||
|
||||
@ -180,7 +168,6 @@ export class DatabaseManager extends DatabaseDemuxBase {
|
||||
try {
|
||||
await fs.copyFile(src, dest);
|
||||
} catch (err) {
|
||||
emitMainProcessError(err);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { getDefaultMetaFieldValueMap } from '../helpers';
|
||||
import { emitMainProcessError, getDefaultMetaFieldValueMap } from '../helpers';
|
||||
import { DatabaseManager } from './manager';
|
||||
import { FieldValueMap, Patch } from './types';
|
||||
|
||||
@ -14,9 +14,13 @@ export async function runPatches(patches: Patch[], dm: DatabaseManager) {
|
||||
async function runPatch(patch: Patch, dm: DatabaseManager): Promise<boolean> {
|
||||
try {
|
||||
await patch.patch.execute(dm);
|
||||
} catch (err) {
|
||||
console.error('PATCH FAILED: ', patch.name);
|
||||
console.error(err);
|
||||
} catch (error) {
|
||||
if (!(error instanceof Error)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
error.message = `Patch Failed: ${patch.name}\n${error.message}`;
|
||||
emitMainProcessError(error, { patchName: patch.name, notifyUser: false });
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -205,7 +205,6 @@ export class StockTransferItem extends Doc {
|
||||
static filters: FiltersMap = {
|
||||
item: (doc: Doc) => {
|
||||
let itemNotFor = 'Sales';
|
||||
console.log(doc.schemaName, doc.isSales);
|
||||
if (doc.isSales) {
|
||||
itemNotFor = 'Purchases';
|
||||
}
|
||||
|
53
src/App.vue
53
src/App.vue
@ -50,11 +50,7 @@ import SetupWizard from './pages/SetupWizard/SetupWizard.vue';
|
||||
import setupInstance from './setup/setupInstance';
|
||||
import { SetupWizardOptions } from './setup/types';
|
||||
import './styles/index.css';
|
||||
import {
|
||||
connectToDatabase,
|
||||
dbErrorActionSymbols,
|
||||
handleDatabaseConnectionError,
|
||||
} from './utils/db';
|
||||
import { connectToDatabase, dbErrorActionSymbols } from './utils/db';
|
||||
import { initializeInstance } from './utils/initialization';
|
||||
import * as injectionKeys from './utils/injectionKeys';
|
||||
import { checkForUpdates } from './utils/ipcCalls';
|
||||
@ -195,57 +191,20 @@ export default defineComponent({
|
||||
return await this.handleConnectionFailed(error, actionSymbol);
|
||||
}
|
||||
|
||||
const setupComplete = await this.getSetupComplete(filePath);
|
||||
if (typeof setupComplete === 'object') {
|
||||
return await this.handleConnectionFailed(
|
||||
setupComplete.error,
|
||||
setupComplete.actionSymbol
|
||||
);
|
||||
}
|
||||
const setupComplete = await fyo.getValue(
|
||||
ModelNameEnum.AccountingSettings,
|
||||
'setupComplete'
|
||||
);
|
||||
|
||||
if (!setupComplete) {
|
||||
this.activeScreen = Screen.SetupWizard;
|
||||
return;
|
||||
}
|
||||
|
||||
await this.initializeInstanceWithErrorHandling(filePath, countryCode);
|
||||
await initializeInstance(filePath, false, countryCode, fyo);
|
||||
await updatePrintTemplates(fyo);
|
||||
await this.setDesk(filePath);
|
||||
},
|
||||
async getSetupComplete(dbPath: string) {
|
||||
try {
|
||||
return (await fyo.getValue(
|
||||
ModelNameEnum.AccountingSettings,
|
||||
'setupComplete'
|
||||
)) as boolean;
|
||||
} catch (error) {
|
||||
if (!(error instanceof Error)) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return {
|
||||
error,
|
||||
actionSymbol: await handleDatabaseConnectionError(error, dbPath),
|
||||
};
|
||||
}
|
||||
},
|
||||
async initializeInstanceWithErrorHandling(
|
||||
dbPath: string,
|
||||
countryCode: string
|
||||
) {
|
||||
try {
|
||||
return await initializeInstance(dbPath, false, countryCode, fyo);
|
||||
} catch (error) {
|
||||
if (!(error instanceof Error)) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
this.handleConnectionFailed(
|
||||
error,
|
||||
await handleDatabaseConnectionError(error, dbPath)
|
||||
);
|
||||
}
|
||||
},
|
||||
async handleConnectionFailed(error: Error, actionSymbol: symbol) {
|
||||
await this.showDbSelector();
|
||||
|
||||
|
@ -76,7 +76,8 @@ export function getErrorLogObject(
|
||||
export async function handleError(
|
||||
logToConsole: boolean,
|
||||
error: Error,
|
||||
more?: Record<string, unknown>
|
||||
more: Record<string, unknown> = {},
|
||||
notifyUser: boolean = true
|
||||
) {
|
||||
if (logToConsole) {
|
||||
console.error(error);
|
||||
@ -86,12 +87,14 @@ export async function handleError(
|
||||
return;
|
||||
}
|
||||
|
||||
const errorLogObj = getErrorLogObject(error, more ?? {});
|
||||
|
||||
const errorLogObj = getErrorLogObject(error, more);
|
||||
await sendError(errorLogObj);
|
||||
const toastProps = getToastProps(errorLogObj);
|
||||
const { showToast } = await import('src/utils/interactive');
|
||||
await showToast(toastProps);
|
||||
|
||||
if (notifyUser) {
|
||||
const toastProps = getToastProps(errorLogObj);
|
||||
const { showToast } = await import('src/utils/interactive');
|
||||
await showToast(toastProps);
|
||||
}
|
||||
}
|
||||
|
||||
export async function handleErrorWithDialog(
|
||||
|
@ -7,11 +7,22 @@ export default function registerIpcRendererListeners() {
|
||||
ipcRenderer.on(
|
||||
IPC_CHANNELS.LOG_MAIN_PROCESS_ERROR,
|
||||
async (_, error, more) => {
|
||||
if (fyo.store.isDevelopment) {
|
||||
console.error(error);
|
||||
if (!(error instanceof Error)) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
await handleError(true, error as Error, more);
|
||||
if (!more) {
|
||||
more = {};
|
||||
}
|
||||
|
||||
if (typeof more !== 'object') {
|
||||
more = { more };
|
||||
}
|
||||
|
||||
more.isMainProcess = true;
|
||||
more.notifyUser ??= true;
|
||||
|
||||
await handleError(true, error, more, more.notifyUser);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -1,5 +1,11 @@
|
||||
import { Fyo, t } from 'fyo';
|
||||
|
||||
type Conn = {
|
||||
countryCode: string;
|
||||
error?: Error;
|
||||
actionSymbol?: typeof dbErrorActionSymbols[keyof typeof dbErrorActionSymbols];
|
||||
};
|
||||
|
||||
export const dbErrorActionSymbols = {
|
||||
SelectFile: Symbol('select-file'),
|
||||
CancelSelection: Symbol('cancel-selection'),
|
||||
@ -10,12 +16,6 @@ const dbErrors = {
|
||||
UnableToAcquireConnection: 'Unable to acquire a connection',
|
||||
} as const;
|
||||
|
||||
type Conn = {
|
||||
countryCode: string;
|
||||
error?: Error;
|
||||
actionSymbol?: typeof dbErrorActionSymbols[keyof typeof dbErrorActionSymbols];
|
||||
};
|
||||
|
||||
export async function connectToDatabase(
|
||||
fyo: Fyo,
|
||||
dbPath: string,
|
||||
|
Loading…
Reference in New Issue
Block a user