Browse Source

fix: improve API server update reliability and logging

- Refactor dbExec in ElectronPlatformService to use proper connection management
- Add comprehensive logging throughout API server update flow
- Fix connection handling in database operations
- Add user feedback notifications for success/failure
- Add verification step after settings update

The main issue was that dbExec wasn't using the same robust connection
management as dbQuery, leading to "SQLite not initialized" errors. Now both
methods use the same connection lifecycle management through enqueueOperation.

Also added detailed logging at each step to help diagnose any future issues:
- AccountViewView component logging
- Database utility operations logging
- Connection state tracking
- Update verification

This should make the API server update more reliable and easier to debug.
sql-absurd-sql-further
Matthew Raymer 3 days ago
parent
commit
9eb07b3258
  1. 8
      electron/src/rt/sqlite-init.ts
  2. 41
      src/services/platforms/ElectronPlatformService.ts
  3. 59
      src/views/AccountViewView.vue

8
electron/src/rt/sqlite-init.ts

@ -268,8 +268,8 @@ const verifyTransactionState = async (database: string): Promise<boolean> => {
// Only update state if it's different
if (isActive !== transactionState.isActive || transactionState.database !== database) {
transactionState.isActive = isActive;
transactionState.lastVerified = new Date();
transactionState.isActive = isActive;
transactionState.lastVerified = new Date();
transactionState.database = isActive ? database : null;
}
@ -526,7 +526,7 @@ export async function initializeSQLite(): Promise<void> {
try {
logger.debug('Executing PRAGMA:', statement);
const result = await pluginState.instance.execute({
database: connectionOptions.database,
database: connectionOptions.database,
statements: statement,
transaction: false
});
@ -900,7 +900,7 @@ export function setupSQLiteHandlers(): void {
});
logger.info('SQLite IPC handlers setup complete');
}
}
// Update transaction management to be more careful
const beginTransaction = async (database: string): Promise<void> => {

41
src/services/platforms/ElectronPlatformService.ts

@ -691,24 +691,35 @@ export class ElectronPlatformService implements PlatformService {
sql: string,
params?: unknown[],
): Promise<{ changes: number; lastId?: number }> {
await this.initializeDatabase();
if (this.dbFatalError) {
throw new Error(
"Database is in a fatal error state. Please restart the app.",
);
}
if (!this.sqlite) {
throw new Error("SQLite not initialized");
throw new Error("Database is in a fatal error state. Please restart the app.");
}
const result = await this.sqlite.run({
database: this.dbName,
statement: sql,
values: params,
return this.enqueueOperation(async () => {
try {
// Get connection (will wait for existing connection if any)
await this.getConnection();
// Execute query
const result = await window.electron!.ipcRenderer.invoke('sqlite-run', {
database: this.dbName,
statement: sql,
values: params
}) as SQLiteQueryResult;
logger.debug("[ElectronPlatformService] [dbExec] Query executed successfully");
return {
changes: result.changes?.changes || 0,
lastId: result.changes?.lastId,
};
} catch (error) {
logger.error("[ElectronPlatformService] [dbExec] Query failed:", error);
throw error;
} finally {
// Release connection after query
await this.releaseConnection();
}
});
return {
changes: result.changes?.changes || 0,
lastId: result.changes?.lastId,
};
}
async initialize(): Promise<void> {

59
src/views/AccountViewView.vue

@ -1886,16 +1886,63 @@ export default class AccountViewView extends Vue {
}
async onClickSaveApiServer() {
await databaseUtil.updateDefaultSettings({
apiServer: this.apiServerInput,
logger.debug("[AccountViewView] Starting API server update", {
current: this.apiServer,
new: this.apiServerInput,
component: 'AccountViewView'
});
if (USE_DEXIE_DB) {
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
try {
logger.debug("[AccountViewView] Calling updateDefaultSettings");
await databaseUtil.updateDefaultSettings({
apiServer: this.apiServerInput,
});
logger.debug("[AccountViewView] updateDefaultSettings completed");
if (USE_DEXIE_DB) {
logger.debug("[AccountViewView] Updating Dexie DB");
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
apiServer: this.apiServerInput,
});
logger.debug("[AccountViewView] Dexie DB update completed");
}
this.apiServer = this.apiServerInput;
logger.debug("[AccountViewView] Local state updated", { apiServer: this.apiServer });
// Verify the update
const settings = await databaseUtil.retrieveSettingsForActiveAccount();
logger.debug("[AccountViewView] Settings verification", {
retrieved: settings.apiServer,
expected: this.apiServerInput,
match: settings.apiServer === this.apiServerInput
});
// Show success notification
this.$notify({
group: "alert",
type: "success",
title: "API Server Updated",
text: "API server settings saved successfully.",
}, 3000);
} catch (error) {
logger.error("[AccountViewView] API server update failed", {
error,
current: this.apiServer,
attempted: this.apiServerInput
});
this.$notify(
{
group: "alert",
type: "danger",
title: "Error Saving API Server",
text: "Failed to save API server settings. Please try again.",
},
5000,
);
}
this.apiServer = this.apiServerInput;
}
async onClickSavePartnerServer() {

Loading…
Cancel
Save