diff --git a/packages/core/utils/src/migrations/index.ts b/packages/core/utils/src/migrations/index.ts index 3affd373af..d4c9478b8a 100644 --- a/packages/core/utils/src/migrations/index.ts +++ b/packages/core/utils/src/migrations/index.ts @@ -15,6 +15,7 @@ export type MigrationsEvents = { migrated: [UmzugMigration] reverting: [UmzugMigration] reverted: [UmzugMigration] + "revert:skipped": [UmzugMigration & { reason: string }] } /** @@ -105,6 +106,29 @@ export class Migrations extends EventEmitter { try { return await migrator.down(options) + } catch (error) { + /** + * This is a very ugly hack to recover from an exception thrown by + * MikrORM when the `down` method is not implemented by the + * migration. + * + * We cannot check if "down" method exists on the migration, because it + * always exists (as inherited from the parent class). Also, throwing + * an exception is important, so that Mikro ORM does not consider the + * given migration as reverted. + */ + if ( + error?.migration && + error?.cause?.message === "This migration cannot be reverted" + ) { + this.emit("revert:skipped", { + ...error.migration, + reason: "Missing down method", + }) + return [] + } + + throw error } finally { migrator["umzug"].clearListeners() await connection.close(true) diff --git a/packages/core/utils/src/modules-sdk/migration-scripts/migration-down.ts b/packages/core/utils/src/modules-sdk/migration-scripts/migration-down.ts index 9663643c55..bf8fd491d3 100644 --- a/packages/core/utils/src/modules-sdk/migration-scripts/migration-down.ts +++ b/packages/core/utils/src/modules-sdk/migration-scripts/migration-down.ts @@ -42,6 +42,9 @@ export function buildRevertMigrationScript({ moduleName, pathToMigrations }) { migrations.on("reverted", (migration) => { logger.info(` ✔ Reverted ${migration.name}`) }) + migrations.on("revert:skipped", (migration) => { + logger.info(` ✔ Skipped ${migration.name}. ${migration.reason}`) + }) try { const result = await migrations.revert()