From 1c7e2c46b2c67215063f0d2b723fca456cf60e67 Mon Sep 17 00:00:00 2001 From: Reed Allman Date: Tue, 20 Mar 2018 11:53:30 -0700 Subject: [PATCH] migratex: return more robust errors (#873) the error itself from up/down & dirty can be improved to show direction and version information to help a user of the package determine where things went wrong, which is useful when a series of migrations are run and the db error itself is not clear about what went wrong exactly. --- api/datastore/sql/migratex/migrate.go | 29 +++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/api/datastore/sql/migratex/migrate.go b/api/datastore/sql/migratex/migrate.go index 20661721d..b717d4f65 100644 --- a/api/datastore/sql/migratex/migrate.go +++ b/api/datastore/sql/migratex/migrate.go @@ -21,9 +21,30 @@ var ( MigrationsTable = "schema_migrations" ErrLocked = errors.New("database is locked") - ErrDirty = errors.New("database is dirty") ) +func migrateErr(version int64, up bool, err error) ErrMigration { + dir := "up" + if !up { + dir = "down" + } + return ErrMigration(fmt.Sprintf("error running migration. version: %v direction: %v err: %v", version, dir, err)) +} + +// ErrMigration represents an error running a specific migration in a specific direction +type ErrMigration string + +func (e ErrMigration) Error() string { return string(e) } + +func dirtyErr(version int64) ErrDirty { + return ErrDirty(fmt.Sprintf("database is dirty. version: %v", version)) +} + +// ErrDirty is an error that is returned when a db is dirty. +type ErrDirty string + +func (e ErrDirty) Error() string { return string(e) } + const ( NilVersion = -1 ) @@ -70,7 +91,7 @@ func migrate(ctx context.Context, db *sqlx.DB, migs []Migration, up bool) error var err error curVersion, dirty, err = Version(ctx, tx) if dirty { - return ErrDirty + return dirtyErr(curVersion) } return err }) @@ -173,7 +194,7 @@ func run(ctx context.Context, db *sqlx.DB, m Migration, up bool) error { // migration has not already been applied. curVersion, dirty, err := Version(ctx, tx) if dirty { - return ErrDirty + return dirtyErr(curVersion) } // enforce monotonicity @@ -199,7 +220,7 @@ func run(ctx context.Context, db *sqlx.DB, m Migration, up bool) error { } if err != nil { - return err + return migrateErr(version, up, err) } err = SetVersion(ctx, tx, version, false)