Elixir version
any
Database and Version
any
Ecto Versions
3.14.0
Database Adapter and Versions (postgrex, myxql, etc)
any (Reproduced with `EctoSQL.TestAdapter)
Current behavior
If a migration module does not implement neither the requested callback nor change/0, Ecto.Migrator.up/4 and down/4 raise Ecto.MigrationError but still modify the schema_migrations table. A broken migration applied during tests/development corrupts the state and requires manual intervention.
Repro:
run a broken migration
defmodule InvalidMigration do
use Ecto.Migration
end
assert_raise Ecto.MigrationError, fn ->
Ecto.Migrator.up(TestRepo, 13, InvalidMigration, log: false)
end
# Incorrect: version 13 was recorded even though no migration ran.
assert Ecto.Migrator.migrated_versions(TestRepo) == [1, 2, 3, 13]
Reason:
do_up/5 and do_down/5 return {:error, %Ecto.MigrationError{}}. In async_migrate_maybe_in_transaction/7, fun_with_status unconditionally calls SchemaMigration.up/4 or SchemaMigration.down/4.
Secondary issue:
With strict_version_order: true, up/4 currently checks version ordering only after do_up/5 returns. An out-of-order migration is applied and its version is committed before Ecto.MigrationError is raised:
assert_raise Ecto.MigrationError, fn ->
Ecto.Migrator.up(TestRepo, 0, ValidMigration,
log: false,
strict_version_order: true
)
end
# Incorrect: migration 0 has already run and is recorded.
assert 0 in Ecto.Migrator.migrated_versions(TestRepo)
This contradicts the documented behavior that strict ordering should abort the migration.
Expected behavior
Broken migrations should not affect schema_migrations table. Retrying after fixing the module should execute the migration instead of returning :already_up or :already_down. With strict_version_order: true, version ordering should be validated before executing any migration commands
Elixir version
any
Database and Version
any
Ecto Versions
3.14.0
Database Adapter and Versions (postgrex, myxql, etc)
any (Reproduced with `EctoSQL.TestAdapter)
Current behavior
If a migration module does not implement neither the requested callback nor
change/0,Ecto.Migrator.up/4anddown/4raiseEcto.MigrationErrorbut still modify theschema_migrationstable. A broken migration applied during tests/development corrupts the state and requires manual intervention.Repro:
run a broken migration
Reason:
do_up/5anddo_down/5return{:error, %Ecto.MigrationError{}}. Inasync_migrate_maybe_in_transaction/7,fun_with_statusunconditionally callsSchemaMigration.up/4orSchemaMigration.down/4.Secondary issue:
With
strict_version_order: true,up/4currently checks version ordering only afterdo_up/5returns. An out-of-order migration is applied and its version is committed beforeEcto.MigrationErroris raised:This contradicts the documented behavior that strict ordering should abort the migration.
Expected behavior
Broken migrations should not affect
schema_migrationstable. Retrying after fixing the module should execute the migration instead of returning:already_upor:already_down. Withstrict_version_order: true, version ordering should be validated before executing any migration commands