fix(db): refuse to roll back a migration that defines no down section
rollback ran a migration's down section when it had one and then deleted its tracking row either way. A migration that changed the schema without a `-- +down` section was therefore recorded as rolled back while its change stayed in the database, and the next migrate replayed statements such as ALTER TABLE ADD COLUMN that cannot run twice, leaving the database stuck between the two states with no way forward or back. It now refuses that case with WRN-DB-MIGRATION-IRREVERSIBLE and leaves the tracking row alone, so the database stays consistent and the operator chooses: add a down section, or write a new migration that reverses the change. The check runs before the lock is taken, so a dry run reports the same refusal rather than promising a rollback that would fail. A migration whose up is empty still rolls back by dropping its tracking row, since there is nothing to undo. That keeps placeholder migrations working, and `wrnexus db rollback` prints the refusal as a message rather than a stack trace. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d3f26ad16e
commit
b807f7b5a7
3 files changed
+95
-3
No files matched your search
+12
-1
@@ -313,7 +313,18 @@ export async function runDbCommand(
|
||||
break;
|
||||
}
|
||||
case "rollback": {
|
||||
const name = await rollback(db, migrationsDir);
|
||||
let name: string | null;
|
||||
try {
|
||||
name = await rollback(db, migrationsDir);
|
||||
} catch (error) {
|
||||
// A migration with no down section is refused rather than half-undone.
|
||||
// That is an operator decision to make, not a stack trace to read.
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
if (!message.startsWith("WRN-DB-MIGRATION-IRREVERSIBLE")) throw error;
|
||||
console.error(`✗ ${message.replace("WRN-DB-MIGRATION-IRREVERSIBLE: ", "")}`);
|
||||
process.exitCode = 1;
|
||||
break;
|
||||
}
|
||||
console.log(name ? `✓ Rolled back ${name}${label}` : `Nothing to roll back${label}.`);
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user