fix(migration): don't crash on idempotent column creation

This commit is contained in:
Elian Doran
2026-04-07 15:30:24 +03:00
parent dc9b0093d9
commit 2cb39ea7e3
2 changed files with 16 additions and 6 deletions

View File

@@ -11,7 +11,8 @@ const MIGRATIONS: (SqlMigration | JsMigration)[] = [
version: 236,
sql: /*sql*/`\
ALTER TABLE blobs ADD COLUMN textRepresentation TEXT DEFAULT NULL;
`
`,
ignoreErrors: true
},
// Add missing database indices for query performance
{
@@ -335,6 +336,8 @@ export default MIGRATIONS;
interface Migration {
version: number;
/** If true, errors during this migration are logged but do not halt the migration process. Useful for migrations that may have already been applied (e.g. adding a column that already exists). */
ignoreErrors?: boolean;
}
interface SqlMigration extends Migration {

View File

@@ -14,6 +14,7 @@ interface MigrationInfo {
* If a function, then the migration is a JavaScript/TypeScript module that will be executed.
*/
migration: string | (() => void);
ignoreErrors?: boolean;
}
async function migrate() {
@@ -56,9 +57,13 @@ async function migrate() {
log.info(`Migration to version ${mig.dbVersion} has been successful.`);
} catch (e: any) {
console.error(e);
crash(t("migration.error_message", { version: mig.dbVersion, stack: e.stack }));
break; // crash() is sometimes async
if (mig.ignoreErrors) {
log.info(`Migration to version ${mig.dbVersion} failed, but ignoreErrors is set. Continuing. Error: ${e.message}`);
} else {
console.error(e);
crash(t("migration.error_message", { version: mig.dbVersion, stack: e.stack }));
break; // crash() is sometimes async
}
}
}
});
@@ -79,14 +84,16 @@ async function prepareMigrations(currentDbVersion: number): Promise<MigrationInf
if ("sql" in migration) {
migrations.push({
dbVersion,
migration: migration.sql
migration: migration.sql,
ignoreErrors: migration.ignoreErrors
});
} else {
// Due to ESM imports, the migration file needs to be imported asynchronously and thus cannot be loaded at migration time (since migration is not asynchronous).
// As such we have to preload the ESM.
migrations.push({
dbVersion,
migration: (await migration.module()).default
migration: (await migration.module()).default,
ignoreErrors: migration.ignoreErrors
});
}
}