Fix database migration errors by improving error handling

- Enhanced migration service to handle duplicate column errors gracefully
- Added detection for 'duplicate column' and 'already exists' errors
- Migration service now marks partially applied migrations as complete
- Prevents Electron app crashes due to cross-platform database conflicts
- Improved robustness for database schema migrations

Fixes database initialization issues when switching between platforms
(web, mobile, electron) that may have different migration states.
This commit is contained in:
Matthew Raymer
2025-06-27 08:29:31 +00:00
parent c13008d476
commit b8b0ebdf4d
3 changed files with 97 additions and 12 deletions

View File

@@ -121,6 +121,11 @@ const MIGRATIONS = [
{
name: "002_add_iViewContent_to_contacts",
sql: `
-- We need to handle the case where iViewContent column might already exist
-- SQLite doesn't support IF NOT EXISTS for ALTER TABLE ADD COLUMN
-- So we'll use a more robust approach with error handling in the migration service
-- First, try to add the column - this will fail silently if it already exists
ALTER TABLE contacts ADD COLUMN iViewContent BOOLEAN DEFAULT TRUE;
`,
},

View File

@@ -119,11 +119,40 @@ export async function runMigrations<T>(
`[MigrationService] Successfully applied migration: ${migration.name}`,
);
} catch (error) {
logger.error(
`[MigrationService] Failed to apply migration ${migration.name}:`,
error,
);
throw new Error(`Migration ${migration.name} failed: ${error}`);
// Handle specific cases where the migration might be partially applied
const errorMessage = String(error).toLowerCase();
// Check if it's a duplicate column error - this means the column already exists
if (errorMessage.includes('duplicate column') ||
errorMessage.includes('column already exists') ||
errorMessage.includes('already exists')) {
logger.warn(
`[MigrationService] Migration ${migration.name} appears to be already applied (${errorMessage}). Marking as complete.`,
);
// Mark the migration as applied since the schema change already exists
try {
await sqlExec("INSERT INTO migrations (name) VALUES (?)", [
migration.name,
]);
logger.info(
`[MigrationService] Successfully marked migration as applied: ${migration.name}`,
);
} catch (insertError) {
// If we can't insert the migration record, log it but don't fail
logger.warn(
`[MigrationService] Could not record migration ${migration.name} as applied:`,
insertError,
);
}
} else {
// For other types of errors, still fail the migration
logger.error(
`[MigrationService] Failed to apply migration ${migration.name}:`,
error,
);
throw new Error(`Migration ${migration.name} failed: ${error}`);
}
}
}
} catch (error) {