From 59f084ea3be2e7ec9d912c1a311402b1e4c40df6 Mon Sep 17 00:00:00 2001 From: Leon Klingele Date: Fri, 24 Oct 2025 01:57:25 +0200 Subject: [PATCH 1/2] feat: remove dependency on "hashicorp/go-multierror" It seems the project has been unmainted for quite some time already, see for example https://github.com/hashicorp/go-multierror/issues/97 and https://github.com/hashicorp/go-multierror/issues/98. This also removes an uneccessary dependency which slims down the go.mod. Go as of version 1.20 supports appending errors by specifying multiple "%w" formatters in the "fmt.Errorf"[^0] function. [^0]: https://pkg.go.dev/fmt#Errorf --- database/cassandra/cassandra.go | 3 +-- database/clickhouse/clickhouse.go | 9 +++++--- database/cockroachdb/cockroachdb.go | 15 ++++++++++---- database/firebird/firebird.go | 9 +++++--- database/mongodb/mongodb.go | 3 +-- database/mysql/mysql.go | 13 +++++++----- database/neo4j/neo4j.go | 31 ++++++++++++++++++++++------ database/pgx/pgx.go | 25 +++++++++++++++------- database/pgx/v5/pgx.go | 13 +++++++----- database/postgres/postgres.go | 13 +++++++----- database/ql/ql.go | 14 +++++++------ database/redshift/redshift.go | 13 +++++++----- database/rqlite/rqlite.go | 3 +-- database/snowflake/snowflake.go | 13 +++++++----- database/spanner/spanner.go | 3 +-- database/sqlcipher/sqlcipher.go | 13 +++++++----- database/sqlite/sqlite.go | 13 +++++++----- database/sqlite3/sqlite3.go | 13 +++++++----- database/sqlserver/sqlserver.go | 7 +++---- database/yugabytedb/yugabytedb.go | 16 +++++++++++---- go.mod | 2 -- go.sum | 5 ----- migrate.go | 20 +++++++++++++----- testing/docker.go | 7 +++++-- util.go | 32 ----------------------------- 25 files changed, 177 insertions(+), 131 deletions(-) diff --git a/database/cassandra/cassandra.go b/database/cassandra/cassandra.go index de25313e0..b5525eae0 100644 --- a/database/cassandra/cassandra.go +++ b/database/cassandra/cassandra.go @@ -13,7 +13,6 @@ import ( "github.com/gocql/gocql" "github.com/golang-migrate/migrate/v4/database" "github.com/golang-migrate/migrate/v4/database/multistmt" - "github.com/hashicorp/go-multierror" ) func init() { @@ -318,7 +317,7 @@ func (c *Cassandra) ensureVersionTable() (err error) { if err == nil { err = e } else { - err = multierror.Append(err, e) + err = fmt.Errorf("%w: %w", err, e) } } }() diff --git a/database/clickhouse/clickhouse.go b/database/clickhouse/clickhouse.go index 6bbce8120..8a952f9f2 100644 --- a/database/clickhouse/clickhouse.go +++ b/database/clickhouse/clickhouse.go @@ -13,7 +13,6 @@ import ( "github.com/golang-migrate/migrate/v4" "github.com/golang-migrate/migrate/v4/database" "github.com/golang-migrate/migrate/v4/database/multistmt" - "github.com/hashicorp/go-multierror" ) var ( @@ -212,7 +211,7 @@ func (ch *ClickHouse) ensureVersionTable() (err error) { if err == nil { err = e } else { - err = multierror.Append(err, e) + err = fmt.Errorf("%w: %w", err, e) } } }() @@ -266,7 +265,11 @@ func (ch *ClickHouse) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - err = multierror.Append(err, errClose) + if err == nil { + err = errClose + } else { + err = fmt.Errorf("%w: %w", err, errClose) + } } }() diff --git a/database/cockroachdb/cockroachdb.go b/database/cockroachdb/cockroachdb.go index 250f907b3..0c2c8934c 100644 --- a/database/cockroachdb/cockroachdb.go +++ b/database/cockroachdb/cockroachdb.go @@ -13,7 +13,6 @@ import ( "github.com/cockroachdb/cockroach-go/v2/crdb" "github.com/golang-migrate/migrate/v4" "github.com/golang-migrate/migrate/v4/database" - "github.com/hashicorp/go-multierror" "github.com/lib/pq" ) @@ -161,7 +160,11 @@ func (c *CockroachDb) Lock() error { } defer func() { if errClose := rows.Close(); errClose != nil { - err = multierror.Append(err, errClose) + if err == nil { + err = errClose + } else { + err = fmt.Errorf("%w: %w", err, errClose) + } } }() @@ -276,7 +279,11 @@ func (c *CockroachDb) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - err = multierror.Append(err, errClose) + if err == nil { + err = errClose + } else { + err = fmt.Errorf("%w: %w", err, errClose) + } } }() @@ -321,7 +328,7 @@ func (c *CockroachDb) ensureVersionTable() (err error) { if err == nil { err = e } else { - err = multierror.Append(err, e) + err = fmt.Errorf("%w: %w", err, e) } } }() diff --git a/database/firebird/firebird.go b/database/firebird/firebird.go index bcece57f3..dca0b4f54 100644 --- a/database/firebird/firebird.go +++ b/database/firebird/firebird.go @@ -12,7 +12,6 @@ import ( "github.com/golang-migrate/migrate/v4" "github.com/golang-migrate/migrate/v4/database" - "github.com/hashicorp/go-multierror" _ "github.com/nakagami/firebirdsql" ) @@ -180,7 +179,11 @@ func (f *Firebird) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - err = multierror.Append(err, errClose) + if err == nil { + err = errClose + } else { + err = fmt.Errorf("%w: %w", err, errClose) + } } }() @@ -226,7 +229,7 @@ func (f *Firebird) ensureVersionTable() (err error) { if err == nil { err = e } else { - err = multierror.Append(err, e) + err = fmt.Errorf("%w: %w", err, e) } } }() diff --git a/database/mongodb/mongodb.go b/database/mongodb/mongodb.go index b1334223a..229778b5b 100644 --- a/database/mongodb/mongodb.go +++ b/database/mongodb/mongodb.go @@ -12,7 +12,6 @@ import ( "github.com/cenkalti/backoff/v4" "github.com/golang-migrate/migrate/v4/database" - "github.com/hashicorp/go-multierror" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" @@ -328,7 +327,7 @@ func (m *Mongo) ensureVersionTable() (err error) { if err == nil { err = e } else { - err = multierror.Append(err, e) + err = fmt.Errorf("%w: %w", err, e) } } }() diff --git a/database/mysql/mysql.go b/database/mysql/mysql.go index 8e807c94b..ec59bad62 100644 --- a/database/mysql/mysql.go +++ b/database/mysql/mysql.go @@ -18,7 +18,6 @@ import ( "github.com/go-sql-driver/mysql" "github.com/golang-migrate/migrate/v4/database" - "github.com/hashicorp/go-multierror" ) var _ database.Driver = (*Mysql)(nil) // explicit compile time type check @@ -362,7 +361,7 @@ func (m *Mysql) SetVersion(version int, dirty bool) error { query := "DELETE FROM `" + m.config.MigrationsTable + "` LIMIT 1" if _, err := tx.ExecContext(context.Background(), query); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = multierror.Append(err, errRollback) + err = fmt.Errorf("%w: %w", err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -374,7 +373,7 @@ func (m *Mysql) SetVersion(version int, dirty bool) error { query := "INSERT INTO `" + m.config.MigrationsTable + "` (version, dirty) VALUES (?, ?)" if _, err := tx.ExecContext(context.Background(), query, version, dirty); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = multierror.Append(err, errRollback) + err = fmt.Errorf("%w: %w", err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -416,7 +415,11 @@ func (m *Mysql) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - err = multierror.Append(err, errClose) + if err == nil { + err = errClose + } else { + err = fmt.Errorf("%w: %w", err, errClose) + } } }() @@ -472,7 +475,7 @@ func (m *Mysql) ensureVersionTable() (err error) { if err == nil { err = e } else { - err = multierror.Append(err, e) + err = fmt.Errorf("%w: %w", err, e) } } }() diff --git a/database/neo4j/neo4j.go b/database/neo4j/neo4j.go index 179e0da60..05e4762fa 100644 --- a/database/neo4j/neo4j.go +++ b/database/neo4j/neo4j.go @@ -10,7 +10,6 @@ import ( "github.com/golang-migrate/migrate/v4/database" "github.com/golang-migrate/migrate/v4/database/multistmt" - "github.com/hashicorp/go-multierror" "github.com/neo4j/neo4j-go-driver/neo4j" ) @@ -141,7 +140,11 @@ func (n *Neo4j) Run(migration io.Reader) (err error) { } defer func() { if cerr := session.Close(); cerr != nil { - err = multierror.Append(err, cerr) + if err == nil { + err = cerr + } else { + err = fmt.Errorf("%w: %w", err, cerr) + } } }() @@ -188,7 +191,11 @@ func (n *Neo4j) SetVersion(version int, dirty bool) (err error) { } defer func() { if cerr := session.Close(); cerr != nil { - err = multierror.Append(err, cerr) + if err == nil { + err = cerr + } else { + err = fmt.Errorf("%w: %w", err, cerr) + } } }() @@ -213,7 +220,11 @@ func (n *Neo4j) Version() (version int, dirty bool, err error) { } defer func() { if cerr := session.Close(); cerr != nil { - err = multierror.Append(err, cerr) + if err == nil { + err = cerr + } else { + err = fmt.Errorf("%w: %w", err, cerr) + } } }() @@ -261,7 +272,11 @@ func (n *Neo4j) Drop() (err error) { } defer func() { if cerr := session.Close(); cerr != nil { - err = multierror.Append(err, cerr) + if err == nil { + err = cerr + } else { + err = fmt.Errorf("%w: %w", err, cerr) + } } }() @@ -278,7 +293,11 @@ func (n *Neo4j) ensureVersionConstraint() (err error) { } defer func() { if cerr := session.Close(); cerr != nil { - err = multierror.Append(err, cerr) + if err == nil { + err = cerr + } else { + err = fmt.Errorf("%w: %w", err, cerr) + } } }() diff --git a/database/pgx/pgx.go b/database/pgx/pgx.go index 98ab5aa18..c9976f72a 100644 --- a/database/pgx/pgx.go +++ b/database/pgx/pgx.go @@ -17,7 +17,6 @@ import ( "github.com/golang-migrate/migrate/v4" "github.com/golang-migrate/migrate/v4/database" "github.com/golang-migrate/migrate/v4/database/multistmt" - "github.com/hashicorp/go-multierror" "github.com/jackc/pgconn" "github.com/jackc/pgerrcode" _ "github.com/jackc/pgx/v4/stdlib" @@ -295,7 +294,11 @@ func (p *Postgres) applyTableLock() error { defer func() { errRollback := tx.Rollback() if errRollback != nil { - err = multierror.Append(err, errRollback) + if err == nil { + err = errRollback + } else { + err = fmt.Errorf("%w: %w", err, errRollback) + } } }() @@ -312,7 +315,11 @@ func (p *Postgres) applyTableLock() error { defer func() { if errClose := rows.Close(); errClose != nil { - err = multierror.Append(err, errClose) + if err == nil { + err = errClose + } else { + err = fmt.Errorf("%w: %w", err, errClose) + } } }() @@ -454,7 +461,7 @@ func (p *Postgres) SetVersion(version int, dirty bool) error { query := `TRUNCATE ` + quoteIdentifier(p.config.migrationsSchemaName) + `.` + quoteIdentifier(p.config.migrationsTableName) if _, err := tx.Exec(query); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = multierror.Append(err, errRollback) + err = fmt.Errorf("%w: %w", err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -466,7 +473,7 @@ func (p *Postgres) SetVersion(version int, dirty bool) error { query = `INSERT INTO ` + quoteIdentifier(p.config.migrationsSchemaName) + `.` + quoteIdentifier(p.config.migrationsTableName) + ` (version, dirty) VALUES ($1, $2)` if _, err := tx.Exec(query, version, dirty); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = multierror.Append(err, errRollback) + err = fmt.Errorf("%w: %w", err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -508,7 +515,11 @@ func (p *Postgres) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - err = multierror.Append(err, errClose) + if err == nil { + err = errClose + } else { + err = fmt.Errorf("%w: %w", err, errClose) + } } }() @@ -559,7 +570,7 @@ func (p *Postgres) ensureVersionTable() (err error) { if err == nil { err = e } else { - err = multierror.Append(err, e) + err = fmt.Errorf("%w: %w", err, e) } } }() diff --git a/database/pgx/v5/pgx.go b/database/pgx/v5/pgx.go index 3a442a050..5fff5532a 100644 --- a/database/pgx/v5/pgx.go +++ b/database/pgx/v5/pgx.go @@ -17,7 +17,6 @@ import ( "github.com/golang-migrate/migrate/v4" "github.com/golang-migrate/migrate/v4/database" "github.com/golang-migrate/migrate/v4/database/multistmt" - "github.com/hashicorp/go-multierror" "github.com/jackc/pgerrcode" "github.com/jackc/pgx/v5/pgconn" _ "github.com/jackc/pgx/v5/stdlib" @@ -345,7 +344,7 @@ func (p *Postgres) SetVersion(version int, dirty bool) error { query := `TRUNCATE ` + quoteIdentifier(p.config.migrationsSchemaName) + `.` + quoteIdentifier(p.config.migrationsTableName) if _, err := tx.Exec(query); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = multierror.Append(err, errRollback) + err = fmt.Errorf("%w: %w", err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -357,7 +356,7 @@ func (p *Postgres) SetVersion(version int, dirty bool) error { query = `INSERT INTO ` + quoteIdentifier(p.config.migrationsSchemaName) + `.` + quoteIdentifier(p.config.migrationsTableName) + ` (version, dirty) VALUES ($1, $2)` if _, err := tx.Exec(query, version, dirty); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = multierror.Append(err, errRollback) + err = fmt.Errorf("%w: %w", err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -399,7 +398,11 @@ func (p *Postgres) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - err = multierror.Append(err, errClose) + if err == nil { + err = errClose + } else { + err = fmt.Errorf("%w: %w", err, errClose) + } } }() @@ -444,7 +447,7 @@ func (p *Postgres) ensureVersionTable() (err error) { if err == nil { err = e } else { - err = multierror.Append(err, e) + err = fmt.Errorf("%w: %w", err, e) } } }() diff --git a/database/postgres/postgres.go b/database/postgres/postgres.go index 6b8a77120..1cfc02d77 100644 --- a/database/postgres/postgres.go +++ b/database/postgres/postgres.go @@ -17,7 +17,6 @@ import ( "github.com/golang-migrate/migrate/v4" "github.com/golang-migrate/migrate/v4/database" "github.com/golang-migrate/migrate/v4/database/multistmt" - "github.com/hashicorp/go-multierror" "github.com/lib/pq" ) @@ -361,7 +360,7 @@ func (p *Postgres) SetVersion(version int, dirty bool) error { query := `TRUNCATE ` + pq.QuoteIdentifier(p.config.migrationsSchemaName) + `.` + pq.QuoteIdentifier(p.config.migrationsTableName) if _, err := tx.Exec(query); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = multierror.Append(err, errRollback) + err = fmt.Errorf("%w: %w", err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -373,7 +372,7 @@ func (p *Postgres) SetVersion(version int, dirty bool) error { query = `INSERT INTO ` + pq.QuoteIdentifier(p.config.migrationsSchemaName) + `.` + pq.QuoteIdentifier(p.config.migrationsTableName) + ` (version, dirty) VALUES ($1, $2)` if _, err := tx.Exec(query, version, dirty); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = multierror.Append(err, errRollback) + err = fmt.Errorf("%w: %w", err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -415,7 +414,11 @@ func (p *Postgres) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - err = multierror.Append(err, errClose) + if err == nil { + err = errClose + } else { + err = fmt.Errorf("%w: %w", err, errClose) + } } }() @@ -460,7 +463,7 @@ func (p *Postgres) ensureVersionTable() (err error) { if err == nil { err = e } else { - err = multierror.Append(err, e) + err = fmt.Errorf("%w: %w", err, e) } } }() diff --git a/database/ql/ql.go b/database/ql/ql.go index 6db6ea303..bd5e3cb3d 100644 --- a/database/ql/ql.go +++ b/database/ql/ql.go @@ -8,8 +8,6 @@ import ( "strings" "sync/atomic" - "github.com/hashicorp/go-multierror" - "github.com/golang-migrate/migrate/v4" "github.com/golang-migrate/migrate/v4/database" _ "modernc.org/ql/driver" @@ -75,7 +73,7 @@ func (m *Ql) ensureVersionTable() (err error) { if err == nil { err = e } else { - err = multierror.Append(err, e) + err = fmt.Errorf("%w: %w", err, e) } } }() @@ -133,7 +131,11 @@ func (m *Ql) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - err = multierror.Append(err, errClose) + if err == nil { + err = errClose + } else { + err = fmt.Errorf("%w: %w", err, errClose) + } } }() @@ -193,7 +195,7 @@ func (m *Ql) executeQuery(query string) error { } if _, err := tx.Exec(query); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = multierror.Append(err, errRollback) + err = fmt.Errorf("%w: %w", err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -221,7 +223,7 @@ func (m *Ql) SetVersion(version int, dirty bool) error { m.config.MigrationsTable) if _, err := tx.Exec(query, version, dirty); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = multierror.Append(err, errRollback) + err = fmt.Errorf("%w: %w", err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } diff --git a/database/redshift/redshift.go b/database/redshift/redshift.go index 9379554ce..5dbc7e4d0 100644 --- a/database/redshift/redshift.go +++ b/database/redshift/redshift.go @@ -14,7 +14,6 @@ import ( "github.com/golang-migrate/migrate/v4" "github.com/golang-migrate/migrate/v4/database" - "github.com/hashicorp/go-multierror" "github.com/lib/pq" ) @@ -216,7 +215,7 @@ func (p *Redshift) SetVersion(version int, dirty bool) error { query := `DELETE FROM "` + p.config.MigrationsTable + `"` if _, err := tx.Exec(query); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = multierror.Append(err, errRollback) + err = fmt.Errorf("%w: %w", err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -228,7 +227,7 @@ func (p *Redshift) SetVersion(version int, dirty bool) error { query = `INSERT INTO "` + p.config.MigrationsTable + `" (version, dirty) VALUES ($1, $2)` if _, err := tx.Exec(query, version, dirty); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = multierror.Append(err, errRollback) + err = fmt.Errorf("%w: %w", err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -270,7 +269,11 @@ func (p *Redshift) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - err = multierror.Append(err, errClose) + if err == nil { + err = errClose + } else { + err = fmt.Errorf("%w: %w", err, errClose) + } } }() @@ -315,7 +318,7 @@ func (p *Redshift) ensureVersionTable() (err error) { if err == nil { err = e } else { - err = multierror.Append(err, e) + err = fmt.Errorf("%w: %w", err, e) } } }() diff --git a/database/rqlite/rqlite.go b/database/rqlite/rqlite.go index b0f8365c5..9f6fa6b99 100644 --- a/database/rqlite/rqlite.go +++ b/database/rqlite/rqlite.go @@ -10,7 +10,6 @@ import ( "github.com/golang-migrate/migrate/v4" "github.com/golang-migrate/migrate/v4/database" - "github.com/hashicorp/go-multierror" "github.com/rqlite/gorqlite" ) @@ -91,7 +90,7 @@ func (r *Rqlite) ensureVersionTable() (err error) { if err == nil { err = e } else { - err = multierror.Append(err, e) + err = fmt.Errorf("%w: %w", err, e) } } }() diff --git a/database/snowflake/snowflake.go b/database/snowflake/snowflake.go index dc0290467..aeb8195e3 100644 --- a/database/snowflake/snowflake.go +++ b/database/snowflake/snowflake.go @@ -11,7 +11,6 @@ import ( "sync/atomic" "github.com/golang-migrate/migrate/v4/database" - "github.com/hashicorp/go-multierror" "github.com/lib/pq" sf "github.com/snowflakedb/gosnowflake" ) @@ -248,7 +247,7 @@ func (p *Snowflake) SetVersion(version int, dirty bool) error { query := `DELETE FROM "` + p.config.MigrationsTable + `"` if _, err := tx.Exec(query); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = multierror.Append(err, errRollback) + err = fmt.Errorf("%w: %w", err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -262,7 +261,7 @@ func (p *Snowflake) SetVersion(version int, dirty bool) error { ` + strconv.FormatBool(dirty) + `)` if _, err := tx.Exec(query); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = multierror.Append(err, errRollback) + err = fmt.Errorf("%w: %w", err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -304,7 +303,11 @@ func (p *Snowflake) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - err = multierror.Append(err, errClose) + if err == nil { + err = errClose + } else { + err = fmt.Errorf("%w: %w", err, errClose) + } } }() @@ -349,7 +352,7 @@ func (p *Snowflake) ensureVersionTable() (err error) { if err == nil { err = e } else { - err = multierror.Append(err, e) + err = fmt.Errorf("%w: %w", err, e) } } }() diff --git a/database/spanner/spanner.go b/database/spanner/spanner.go index b17280dea..4a08bf232 100644 --- a/database/spanner/spanner.go +++ b/database/spanner/spanner.go @@ -20,7 +20,6 @@ import ( "github.com/golang-migrate/migrate/v4/database" adminpb "cloud.google.com/go/spanner/admin/database/apiv1/databasepb" - "github.com/hashicorp/go-multierror" "google.golang.org/api/iterator" ) @@ -302,7 +301,7 @@ func (s *Spanner) ensureVersionTable() (err error) { if err == nil { err = e } else { - err = multierror.Append(err, e) + err = fmt.Errorf("%w: %w", err, e) } } }() diff --git a/database/sqlcipher/sqlcipher.go b/database/sqlcipher/sqlcipher.go index ce5fff9f4..2b6da4a14 100644 --- a/database/sqlcipher/sqlcipher.go +++ b/database/sqlcipher/sqlcipher.go @@ -11,7 +11,6 @@ import ( "github.com/golang-migrate/migrate/v4" "github.com/golang-migrate/migrate/v4/database" - "github.com/hashicorp/go-multierror" _ "github.com/mutecomm/go-sqlcipher/v4" ) @@ -75,7 +74,7 @@ func (m *Sqlite) ensureVersionTable() (err error) { if err == nil { err = e } else { - err = multierror.Append(err, e) + err = fmt.Errorf("%w: %w", err, e) } } }() @@ -140,7 +139,11 @@ func (m *Sqlite) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - err = multierror.Append(err, errClose) + if err == nil { + err = errClose + } else { + err = fmt.Errorf("%w: %w", err, errClose) + } } }() @@ -210,7 +213,7 @@ func (m *Sqlite) executeQuery(query string) error { } if _, err := tx.Exec(query); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = multierror.Append(err, errRollback) + err = fmt.Errorf("%w: %w", err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -245,7 +248,7 @@ func (m *Sqlite) SetVersion(version int, dirty bool) error { query := fmt.Sprintf(`INSERT INTO %s (version, dirty) VALUES (?, ?)`, m.config.MigrationsTable) if _, err := tx.Exec(query, version, dirty); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = multierror.Append(err, errRollback) + err = fmt.Errorf("%w: %w", err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } diff --git a/database/sqlite/sqlite.go b/database/sqlite/sqlite.go index bad5b83d2..8f1e1a590 100644 --- a/database/sqlite/sqlite.go +++ b/database/sqlite/sqlite.go @@ -11,7 +11,6 @@ import ( "github.com/golang-migrate/migrate/v4" "github.com/golang-migrate/migrate/v4/database" - "github.com/hashicorp/go-multierror" _ "modernc.org/sqlite" ) @@ -75,7 +74,7 @@ func (m *Sqlite) ensureVersionTable() (err error) { if err == nil { err = e } else { - err = multierror.Append(err, e) + err = fmt.Errorf("%w: %w", err, e) } } }() @@ -140,7 +139,11 @@ func (m *Sqlite) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - err = multierror.Append(err, errClose) + if err == nil { + err = errClose + } else { + err = fmt.Errorf("%w: %w", err, errClose) + } } }() @@ -210,7 +213,7 @@ func (m *Sqlite) executeQuery(query string) error { } if _, err := tx.Exec(query); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = multierror.Append(err, errRollback) + err = fmt.Errorf("%w: %w", err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -245,7 +248,7 @@ func (m *Sqlite) SetVersion(version int, dirty bool) error { query := fmt.Sprintf(`INSERT INTO %s (version, dirty) VALUES (?, ?)`, m.config.MigrationsTable) if _, err := tx.Exec(query, version, dirty); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = multierror.Append(err, errRollback) + err = fmt.Errorf("%w: %w", err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } diff --git a/database/sqlite3/sqlite3.go b/database/sqlite3/sqlite3.go index 9035dee33..8698661de 100644 --- a/database/sqlite3/sqlite3.go +++ b/database/sqlite3/sqlite3.go @@ -11,7 +11,6 @@ import ( "github.com/golang-migrate/migrate/v4" "github.com/golang-migrate/migrate/v4/database" - "github.com/hashicorp/go-multierror" _ "github.com/mattn/go-sqlite3" ) @@ -75,7 +74,7 @@ func (m *Sqlite) ensureVersionTable() (err error) { if err == nil { err = e } else { - err = multierror.Append(err, e) + err = fmt.Errorf("%w: %w", err, e) } } }() @@ -140,7 +139,11 @@ func (m *Sqlite) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - err = multierror.Append(err, errClose) + if err == nil { + err = errClose + } else { + err = fmt.Errorf("%w: %w", err, errClose) + } } }() @@ -210,7 +213,7 @@ func (m *Sqlite) executeQuery(query string) error { } if _, err := tx.Exec(query); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = multierror.Append(err, errRollback) + err = fmt.Errorf("%w: %w", err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -245,7 +248,7 @@ func (m *Sqlite) SetVersion(version int, dirty bool) error { query := fmt.Sprintf(`INSERT INTO %s (version, dirty) VALUES (?, ?)`, m.config.MigrationsTable) if _, err := tx.Exec(query, version, dirty); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = multierror.Append(err, errRollback) + err = fmt.Errorf("%w: %w", err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } diff --git a/database/sqlserver/sqlserver.go b/database/sqlserver/sqlserver.go index 51e1b777a..aa53a58c0 100644 --- a/database/sqlserver/sqlserver.go +++ b/database/sqlserver/sqlserver.go @@ -13,7 +13,6 @@ import ( "github.com/Azure/go-autorest/autorest/adal" "github.com/golang-migrate/migrate/v4" "github.com/golang-migrate/migrate/v4/database" - "github.com/hashicorp/go-multierror" mssql "github.com/microsoft/go-mssqldb" // mssql support ) @@ -271,7 +270,7 @@ func (ss *SQLServer) SetVersion(version int, dirty bool) error { query := `TRUNCATE TABLE ` + ss.getMigrationTable() if _, err := tx.Exec(query); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = multierror.Append(err, errRollback) + err = fmt.Errorf("%w: %w", err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -287,7 +286,7 @@ func (ss *SQLServer) SetVersion(version int, dirty bool) error { query = `INSERT INTO ` + ss.getMigrationTable() + ` (version, dirty) VALUES (@p1, @p2)` if _, err := tx.Exec(query, version, dirtyBit); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = multierror.Append(err, errRollback) + err = fmt.Errorf("%w: %w", err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -362,7 +361,7 @@ func (ss *SQLServer) ensureVersionTable() (err error) { if err == nil { err = e } else { - err = multierror.Append(err, e) + err = fmt.Errorf("%w: %w", err, e) } } }() diff --git a/database/yugabytedb/yugabytedb.go b/database/yugabytedb/yugabytedb.go index f5abbf301..3b30ce2fd 100644 --- a/database/yugabytedb/yugabytedb.go +++ b/database/yugabytedb/yugabytedb.go @@ -4,6 +4,7 @@ import ( "context" "database/sql" "errors" + "fmt" "io" "net/url" "regexp" @@ -14,7 +15,6 @@ import ( "github.com/cenkalti/backoff/v4" "github.com/golang-migrate/migrate/v4" "github.com/golang-migrate/migrate/v4/database" - "github.com/hashicorp/go-multierror" "github.com/jackc/pgconn" "github.com/jackc/pgerrcode" "github.com/lib/pq" @@ -206,7 +206,11 @@ func (c *YugabyteDB) Lock() error { } defer func() { if errClose := rows.Close(); errClose != nil { - err = multierror.Append(err, errClose) + if err == nil { + err = errClose + } else { + err = fmt.Errorf("%w: %w", err, errClose) + } } }() @@ -320,7 +324,11 @@ func (c *YugabyteDB) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - err = multierror.Append(err, errClose) + if err == nil { + err = errClose + } else { + err = fmt.Errorf("%w: %w", err, errClose) + } } }() @@ -363,7 +371,7 @@ func (c *YugabyteDB) ensureVersionTable() (err error) { if err == nil { err = e } else { - err = multierror.Append(err, e) + err = fmt.Errorf("%w: %w", err, e) } } }() diff --git a/go.mod b/go.mod index ef36567a1..f2fc1ca4a 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,6 @@ require ( github.com/gobuffalo/here v0.6.0 github.com/gocql/gocql v0.0.0-20210515062232-b7ef815b4556 github.com/google/go-github/v39 v39.2.0 - github.com/hashicorp/go-multierror v1.1.1 github.com/jackc/pgconn v1.14.3 github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa github.com/jackc/pgx/v4 v4.18.2 @@ -135,7 +134,6 @@ require ( github.com/gorilla/mux v1.7.4 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect github.com/jackc/pgio v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect diff --git a/go.sum b/go.sum index 8de37ad10..2a6547cf7 100644 --- a/go.sum +++ b/go.sum @@ -316,11 +316,6 @@ github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8 github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= diff --git a/migrate.go b/migrate.go index 266cc04eb..bc1c1f867 100644 --- a/migrate.go +++ b/migrate.go @@ -11,8 +11,6 @@ import ( "sync" "time" - "github.com/hashicorp/go-multierror" - "github.com/golang-migrate/migrate/v4/database" iurl "github.com/golang-migrate/migrate/v4/internal/url" "github.com/golang-migrate/migrate/v4/source" @@ -781,7 +779,11 @@ func (m *Migrate) versionExists(version uint) (result error) { if err == nil { defer func() { if errClose := up.Close(); errClose != nil { - result = multierror.Append(result, errClose) + if result == nil { + result = errClose + } else { + result = fmt.Errorf("%w: %w", err, errClose) + } } }() } @@ -796,7 +798,11 @@ func (m *Migrate) versionExists(version uint) (result error) { if err == nil { defer func() { if errClose := down.Close(); errClose != nil { - result = multierror.Append(result, errClose) + if result == nil { + result = errClose + } else { + result = fmt.Errorf("%w: %w", err, errClose) + } } }() } @@ -954,7 +960,11 @@ func (m *Migrate) unlock() error { // if a prevErr is not nil. func (m *Migrate) unlockErr(prevErr error) error { if err := m.unlock(); err != nil { - return multierror.Append(prevErr, err) + if prevErr == nil { + prevErr = err + } else { + prevErr = fmt.Errorf("%w: %w", err, prevErr) + } } return prevErr } diff --git a/testing/docker.go b/testing/docker.go index 5d4e1f0e4..29b9dc73b 100644 --- a/testing/docker.go +++ b/testing/docker.go @@ -19,7 +19,6 @@ import ( dockerimage "github.com/docker/docker/api/types/image" dockernetwork "github.com/docker/docker/api/types/network" dockerclient "github.com/docker/docker/client" - "github.com/hashicorp/go-multierror" ) func NewDockerContainer(t testing.TB, image string, env []string, cmd []string) (*DockerContainer, error) { @@ -79,7 +78,11 @@ func (d *DockerContainer) PullImage() (err error) { } defer func() { if errClose := r.Close(); errClose != nil { - err = multierror.Append(errClose) + if err == nil { + err = errClose + } else { + err = fmt.Errorf("%w: %w", err, errClose) + } } }() diff --git a/util.go b/util.go index 663d68f16..8232e2043 100644 --- a/util.go +++ b/util.go @@ -3,40 +3,8 @@ package migrate import ( "fmt" nurl "net/url" - "strings" ) -// MultiError holds multiple errors. -// -// Deprecated: Use github.com/hashicorp/go-multierror instead -type MultiError struct { - Errs []error -} - -// NewMultiError returns an error type holding multiple errors. -// -// Deprecated: Use github.com/hashicorp/go-multierror instead -func NewMultiError(errs ...error) MultiError { - compactErrs := make([]error, 0) - for _, e := range errs { - if e != nil { - compactErrs = append(compactErrs, e) - } - } - return MultiError{compactErrs} -} - -// Error implements error. Multiple errors are concatenated with 'and's. -func (m MultiError) Error() string { - var strs = make([]string, 0) - for _, e := range m.Errs { - if len(e.Error()) > 0 { - strs = append(strs, e.Error()) - } - } - return strings.Join(strs, " and ") -} - // suint safely converts int to uint // see https://goo.gl/wEcqof // see https://goo.gl/pai7Dr From 1996ec881dbe6f67e0ae8b101dbd77c7fcceedd7 Mon Sep 17 00:00:00 2001 From: Leon Klingele Date: Fri, 24 Oct 2025 02:10:04 +0200 Subject: [PATCH 2/2] feat: use errors.Join to combine multiple errors As an update to the previous commit 59f084ea3be2e7ec9d912c1a311402b1e4c40df6, use "errors.Join"[^0] instead of multiple "%w" formatters for "fmt.Errorf". [^0]: https://pkg.go.dev/errors#Join --- database/cassandra/cassandra.go | 6 +----- database/clickhouse/clickhouse.go | 13 +++--------- database/cockroachdb/cockroachdb.go | 19 ++++-------------- database/firebird/firebird.go | 13 +++--------- database/mongodb/mongodb.go | 7 ++----- database/mysql/mysql.go | 17 +++++----------- database/neo4j/neo4j.go | 31 ++++++----------------------- database/pgx/pgx.go | 29 +++++++-------------------- database/pgx/v5/pgx.go | 17 +++++----------- database/postgres/postgres.go | 17 +++++----------- database/ql/ql.go | 17 +++++----------- database/redshift/redshift.go | 17 +++++----------- database/rqlite/rqlite.go | 7 ++----- database/snowflake/snowflake.go | 17 +++++----------- database/spanner/spanner.go | 6 +----- database/sqlcipher/sqlcipher.go | 17 +++++----------- database/sqlite/sqlite.go | 17 +++++----------- database/sqlite3/sqlite3.go | 17 +++++----------- database/sqlserver/sqlserver.go | 11 ++++------ database/yugabytedb/yugabytedb.go | 19 +++--------------- migrate.go | 18 +++-------------- testing/docker.go | 6 +----- 22 files changed, 85 insertions(+), 253 deletions(-) diff --git a/database/cassandra/cassandra.go b/database/cassandra/cassandra.go index b5525eae0..815427d12 100644 --- a/database/cassandra/cassandra.go +++ b/database/cassandra/cassandra.go @@ -314,11 +314,7 @@ func (c *Cassandra) ensureVersionTable() (err error) { defer func() { if e := c.Unlock(); e != nil { - if err == nil { - err = e - } else { - err = fmt.Errorf("%w: %w", err, e) - } + err = errors.Join(err, e) } }() diff --git a/database/clickhouse/clickhouse.go b/database/clickhouse/clickhouse.go index 8a952f9f2..819af0664 100644 --- a/database/clickhouse/clickhouse.go +++ b/database/clickhouse/clickhouse.go @@ -2,6 +2,7 @@ package clickhouse import ( "database/sql" + "errors" "fmt" "io" "net/url" @@ -208,11 +209,7 @@ func (ch *ClickHouse) ensureVersionTable() (err error) { defer func() { if e := ch.Unlock(); e != nil { - if err == nil { - err = e - } else { - err = fmt.Errorf("%w: %w", err, e) - } + err = errors.Join(err, e) } }() @@ -265,11 +262,7 @@ func (ch *ClickHouse) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - if err == nil { - err = errClose - } else { - err = fmt.Errorf("%w: %w", err, errClose) - } + err = errors.Join(err, errClose) } }() diff --git a/database/cockroachdb/cockroachdb.go b/database/cockroachdb/cockroachdb.go index 0c2c8934c..7af1d2efd 100644 --- a/database/cockroachdb/cockroachdb.go +++ b/database/cockroachdb/cockroachdb.go @@ -3,6 +3,7 @@ package cockroachdb import ( "context" "database/sql" + "errors" "fmt" "io" nurl "net/url" @@ -160,11 +161,7 @@ func (c *CockroachDb) Lock() error { } defer func() { if errClose := rows.Close(); errClose != nil { - if err == nil { - err = errClose - } else { - err = fmt.Errorf("%w: %w", err, errClose) - } + err = errors.Join(err, errClose) } }() @@ -279,11 +276,7 @@ func (c *CockroachDb) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - if err == nil { - err = errClose - } else { - err = fmt.Errorf("%w: %w", err, errClose) - } + err = errors.Join(err, errClose) } }() @@ -325,11 +318,7 @@ func (c *CockroachDb) ensureVersionTable() (err error) { defer func() { if e := c.Unlock(); e != nil { - if err == nil { - err = e - } else { - err = fmt.Errorf("%w: %w", err, e) - } + err = errors.Join(err, e) } }() diff --git a/database/firebird/firebird.go b/database/firebird/firebird.go index dca0b4f54..d3b00115b 100644 --- a/database/firebird/firebird.go +++ b/database/firebird/firebird.go @@ -5,6 +5,7 @@ package firebird import ( "context" "database/sql" + "errors" "fmt" "io" nurl "net/url" @@ -179,11 +180,7 @@ func (f *Firebird) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - if err == nil { - err = errClose - } else { - err = fmt.Errorf("%w: %w", err, errClose) - } + err = errors.Join(err, errClose) } }() @@ -226,11 +223,7 @@ func (f *Firebird) ensureVersionTable() (err error) { defer func() { if e := f.Unlock(); e != nil { - if err == nil { - err = e - } else { - err = fmt.Errorf("%w: %w", err, e) - } + err = errors.Join(err, e) } }() diff --git a/database/mongodb/mongodb.go b/database/mongodb/mongodb.go index 229778b5b..a08347110 100644 --- a/database/mongodb/mongodb.go +++ b/database/mongodb/mongodb.go @@ -2,6 +2,7 @@ package mongodb import ( "context" + "errors" "fmt" "io" "net/url" @@ -324,11 +325,7 @@ func (m *Mongo) ensureVersionTable() (err error) { defer func() { if e := m.Unlock(); e != nil { - if err == nil { - err = e - } else { - err = fmt.Errorf("%w: %w", err, e) - } + err = errors.Join(err, e) } }() diff --git a/database/mysql/mysql.go b/database/mysql/mysql.go index ec59bad62..61a59d295 100644 --- a/database/mysql/mysql.go +++ b/database/mysql/mysql.go @@ -7,6 +7,7 @@ import ( "crypto/tls" "crypto/x509" "database/sql" + "errors" "fmt" "io" nurl "net/url" @@ -361,7 +362,7 @@ func (m *Mysql) SetVersion(version int, dirty bool) error { query := "DELETE FROM `" + m.config.MigrationsTable + "` LIMIT 1" if _, err := tx.ExecContext(context.Background(), query); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = fmt.Errorf("%w: %w", err, errRollback) + err = errors.Join(err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -373,7 +374,7 @@ func (m *Mysql) SetVersion(version int, dirty bool) error { query := "INSERT INTO `" + m.config.MigrationsTable + "` (version, dirty) VALUES (?, ?)" if _, err := tx.ExecContext(context.Background(), query, version, dirty); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = fmt.Errorf("%w: %w", err, errRollback) + err = errors.Join(err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -415,11 +416,7 @@ func (m *Mysql) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - if err == nil { - err = errClose - } else { - err = fmt.Errorf("%w: %w", err, errClose) - } + err = errors.Join(err, errClose) } }() @@ -472,11 +469,7 @@ func (m *Mysql) ensureVersionTable() (err error) { defer func() { if e := m.Unlock(); e != nil { - if err == nil { - err = e - } else { - err = fmt.Errorf("%w: %w", err, e) - } + err = errors.Join(err, e) } }() diff --git a/database/neo4j/neo4j.go b/database/neo4j/neo4j.go index 05e4762fa..f6ab07a87 100644 --- a/database/neo4j/neo4j.go +++ b/database/neo4j/neo4j.go @@ -2,6 +2,7 @@ package neo4j import ( "bytes" + "errors" "fmt" "io" neturl "net/url" @@ -140,11 +141,7 @@ func (n *Neo4j) Run(migration io.Reader) (err error) { } defer func() { if cerr := session.Close(); cerr != nil { - if err == nil { - err = cerr - } else { - err = fmt.Errorf("%w: %w", err, cerr) - } + err = errors.Join(err, cerr) } }() @@ -191,11 +188,7 @@ func (n *Neo4j) SetVersion(version int, dirty bool) (err error) { } defer func() { if cerr := session.Close(); cerr != nil { - if err == nil { - err = cerr - } else { - err = fmt.Errorf("%w: %w", err, cerr) - } + err = errors.Join(err, cerr) } }() @@ -220,11 +213,7 @@ func (n *Neo4j) Version() (version int, dirty bool, err error) { } defer func() { if cerr := session.Close(); cerr != nil { - if err == nil { - err = cerr - } else { - err = fmt.Errorf("%w: %w", err, cerr) - } + err = errors.Join(err, cerr) } }() @@ -272,11 +261,7 @@ func (n *Neo4j) Drop() (err error) { } defer func() { if cerr := session.Close(); cerr != nil { - if err == nil { - err = cerr - } else { - err = fmt.Errorf("%w: %w", err, cerr) - } + err = errors.Join(err, cerr) } }() @@ -293,11 +278,7 @@ func (n *Neo4j) ensureVersionConstraint() (err error) { } defer func() { if cerr := session.Close(); cerr != nil { - if err == nil { - err = cerr - } else { - err = fmt.Errorf("%w: %w", err, cerr) - } + err = errors.Join(err, cerr) } }() diff --git a/database/pgx/pgx.go b/database/pgx/pgx.go index c9976f72a..c84e70dfc 100644 --- a/database/pgx/pgx.go +++ b/database/pgx/pgx.go @@ -5,6 +5,7 @@ package pgx import ( "context" "database/sql" + "errors" "fmt" "io" nurl "net/url" @@ -294,11 +295,7 @@ func (p *Postgres) applyTableLock() error { defer func() { errRollback := tx.Rollback() if errRollback != nil { - if err == nil { - err = errRollback - } else { - err = fmt.Errorf("%w: %w", err, errRollback) - } + err = errors.Join(err, errRollback) } }() @@ -315,11 +312,7 @@ func (p *Postgres) applyTableLock() error { defer func() { if errClose := rows.Close(); errClose != nil { - if err == nil { - err = errClose - } else { - err = fmt.Errorf("%w: %w", err, errClose) - } + err = errors.Join(err, errClose) } }() @@ -461,7 +454,7 @@ func (p *Postgres) SetVersion(version int, dirty bool) error { query := `TRUNCATE ` + quoteIdentifier(p.config.migrationsSchemaName) + `.` + quoteIdentifier(p.config.migrationsTableName) if _, err := tx.Exec(query); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = fmt.Errorf("%w: %w", err, errRollback) + err = errors.Join(err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -473,7 +466,7 @@ func (p *Postgres) SetVersion(version int, dirty bool) error { query = `INSERT INTO ` + quoteIdentifier(p.config.migrationsSchemaName) + `.` + quoteIdentifier(p.config.migrationsTableName) + ` (version, dirty) VALUES ($1, $2)` if _, err := tx.Exec(query, version, dirty); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = fmt.Errorf("%w: %w", err, errRollback) + err = errors.Join(err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -515,11 +508,7 @@ func (p *Postgres) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - if err == nil { - err = errClose - } else { - err = fmt.Errorf("%w: %w", err, errClose) - } + err = errors.Join(err, errClose) } }() @@ -567,11 +556,7 @@ func (p *Postgres) ensureVersionTable() (err error) { defer func() { if e := p.Unlock(); e != nil { - if err == nil { - err = e - } else { - err = fmt.Errorf("%w: %w", err, e) - } + err = errors.Join(err, e) } }() diff --git a/database/pgx/v5/pgx.go b/database/pgx/v5/pgx.go index 5fff5532a..ee1960fe5 100644 --- a/database/pgx/v5/pgx.go +++ b/database/pgx/v5/pgx.go @@ -5,6 +5,7 @@ package pgx import ( "context" "database/sql" + "errors" "fmt" "io" nurl "net/url" @@ -344,7 +345,7 @@ func (p *Postgres) SetVersion(version int, dirty bool) error { query := `TRUNCATE ` + quoteIdentifier(p.config.migrationsSchemaName) + `.` + quoteIdentifier(p.config.migrationsTableName) if _, err := tx.Exec(query); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = fmt.Errorf("%w: %w", err, errRollback) + err = errors.Join(err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -356,7 +357,7 @@ func (p *Postgres) SetVersion(version int, dirty bool) error { query = `INSERT INTO ` + quoteIdentifier(p.config.migrationsSchemaName) + `.` + quoteIdentifier(p.config.migrationsTableName) + ` (version, dirty) VALUES ($1, $2)` if _, err := tx.Exec(query, version, dirty); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = fmt.Errorf("%w: %w", err, errRollback) + err = errors.Join(err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -398,11 +399,7 @@ func (p *Postgres) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - if err == nil { - err = errClose - } else { - err = fmt.Errorf("%w: %w", err, errClose) - } + err = errors.Join(err, errClose) } }() @@ -444,11 +441,7 @@ func (p *Postgres) ensureVersionTable() (err error) { defer func() { if e := p.Unlock(); e != nil { - if err == nil { - err = e - } else { - err = fmt.Errorf("%w: %w", err, e) - } + err = errors.Join(err, e) } }() diff --git a/database/postgres/postgres.go b/database/postgres/postgres.go index 1cfc02d77..7a0f546dd 100644 --- a/database/postgres/postgres.go +++ b/database/postgres/postgres.go @@ -5,6 +5,7 @@ package postgres import ( "context" "database/sql" + "errors" "fmt" "io" nurl "net/url" @@ -360,7 +361,7 @@ func (p *Postgres) SetVersion(version int, dirty bool) error { query := `TRUNCATE ` + pq.QuoteIdentifier(p.config.migrationsSchemaName) + `.` + pq.QuoteIdentifier(p.config.migrationsTableName) if _, err := tx.Exec(query); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = fmt.Errorf("%w: %w", err, errRollback) + err = errors.Join(err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -372,7 +373,7 @@ func (p *Postgres) SetVersion(version int, dirty bool) error { query = `INSERT INTO ` + pq.QuoteIdentifier(p.config.migrationsSchemaName) + `.` + pq.QuoteIdentifier(p.config.migrationsTableName) + ` (version, dirty) VALUES ($1, $2)` if _, err := tx.Exec(query, version, dirty); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = fmt.Errorf("%w: %w", err, errRollback) + err = errors.Join(err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -414,11 +415,7 @@ func (p *Postgres) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - if err == nil { - err = errClose - } else { - err = fmt.Errorf("%w: %w", err, errClose) - } + err = errors.Join(err, errClose) } }() @@ -460,11 +457,7 @@ func (p *Postgres) ensureVersionTable() (err error) { defer func() { if e := p.Unlock(); e != nil { - if err == nil { - err = e - } else { - err = fmt.Errorf("%w: %w", err, e) - } + err = errors.Join(err, e) } }() diff --git a/database/ql/ql.go b/database/ql/ql.go index bd5e3cb3d..31abbfbbb 100644 --- a/database/ql/ql.go +++ b/database/ql/ql.go @@ -2,6 +2,7 @@ package ql import ( "database/sql" + "errors" "fmt" "io" nurl "net/url" @@ -70,11 +71,7 @@ func (m *Ql) ensureVersionTable() (err error) { defer func() { if e := m.Unlock(); e != nil { - if err == nil { - err = e - } else { - err = fmt.Errorf("%w: %w", err, e) - } + err = errors.Join(err, e) } }() @@ -131,11 +128,7 @@ func (m *Ql) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - if err == nil { - err = errClose - } else { - err = fmt.Errorf("%w: %w", err, errClose) - } + err = errors.Join(err, errClose) } }() @@ -195,7 +188,7 @@ func (m *Ql) executeQuery(query string) error { } if _, err := tx.Exec(query); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = fmt.Errorf("%w: %w", err, errRollback) + err = errors.Join(err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -223,7 +216,7 @@ func (m *Ql) SetVersion(version int, dirty bool) error { m.config.MigrationsTable) if _, err := tx.Exec(query, version, dirty); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = fmt.Errorf("%w: %w", err, errRollback) + err = errors.Join(err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } diff --git a/database/redshift/redshift.go b/database/redshift/redshift.go index 5dbc7e4d0..d8b91db88 100644 --- a/database/redshift/redshift.go +++ b/database/redshift/redshift.go @@ -5,6 +5,7 @@ package redshift import ( "context" "database/sql" + "errors" "fmt" "io" nurl "net/url" @@ -215,7 +216,7 @@ func (p *Redshift) SetVersion(version int, dirty bool) error { query := `DELETE FROM "` + p.config.MigrationsTable + `"` if _, err := tx.Exec(query); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = fmt.Errorf("%w: %w", err, errRollback) + err = errors.Join(err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -227,7 +228,7 @@ func (p *Redshift) SetVersion(version int, dirty bool) error { query = `INSERT INTO "` + p.config.MigrationsTable + `" (version, dirty) VALUES ($1, $2)` if _, err := tx.Exec(query, version, dirty); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = fmt.Errorf("%w: %w", err, errRollback) + err = errors.Join(err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -269,11 +270,7 @@ func (p *Redshift) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - if err == nil { - err = errClose - } else { - err = fmt.Errorf("%w: %w", err, errClose) - } + err = errors.Join(err, errClose) } }() @@ -315,11 +312,7 @@ func (p *Redshift) ensureVersionTable() (err error) { defer func() { if e := p.Unlock(); e != nil { - if err == nil { - err = e - } else { - err = fmt.Errorf("%w: %w", err, e) - } + err = errors.Join(err, e) } }() diff --git a/database/rqlite/rqlite.go b/database/rqlite/rqlite.go index 9f6fa6b99..fcab3f8ab 100644 --- a/database/rqlite/rqlite.go +++ b/database/rqlite/rqlite.go @@ -1,6 +1,7 @@ package rqlite import ( + "errors" "fmt" "io" nurl "net/url" @@ -87,11 +88,7 @@ func (r *Rqlite) ensureVersionTable() (err error) { defer func() { if e := r.Unlock(); e != nil { - if err == nil { - err = e - } else { - err = fmt.Errorf("%w: %w", err, e) - } + err = errors.Join(err, e) } }() diff --git a/database/snowflake/snowflake.go b/database/snowflake/snowflake.go index aeb8195e3..8611e18e6 100644 --- a/database/snowflake/snowflake.go +++ b/database/snowflake/snowflake.go @@ -3,6 +3,7 @@ package snowflake import ( "context" "database/sql" + "errors" "fmt" "io" nurl "net/url" @@ -247,7 +248,7 @@ func (p *Snowflake) SetVersion(version int, dirty bool) error { query := `DELETE FROM "` + p.config.MigrationsTable + `"` if _, err := tx.Exec(query); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = fmt.Errorf("%w: %w", err, errRollback) + err = errors.Join(err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -261,7 +262,7 @@ func (p *Snowflake) SetVersion(version int, dirty bool) error { ` + strconv.FormatBool(dirty) + `)` if _, err := tx.Exec(query); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = fmt.Errorf("%w: %w", err, errRollback) + err = errors.Join(err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -303,11 +304,7 @@ func (p *Snowflake) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - if err == nil { - err = errClose - } else { - err = fmt.Errorf("%w: %w", err, errClose) - } + err = errors.Join(err, errClose) } }() @@ -349,11 +346,7 @@ func (p *Snowflake) ensureVersionTable() (err error) { defer func() { if e := p.Unlock(); e != nil { - if err == nil { - err = e - } else { - err = fmt.Errorf("%w: %w", err, e) - } + err = errors.Join(err, e) } }() diff --git a/database/spanner/spanner.go b/database/spanner/spanner.go index 4a08bf232..914c79532 100644 --- a/database/spanner/spanner.go +++ b/database/spanner/spanner.go @@ -298,11 +298,7 @@ func (s *Spanner) ensureVersionTable() (err error) { defer func() { if e := s.Unlock(); e != nil { - if err == nil { - err = e - } else { - err = fmt.Errorf("%w: %w", err, e) - } + err = errors.Join(err, e) } }() diff --git a/database/sqlcipher/sqlcipher.go b/database/sqlcipher/sqlcipher.go index 2b6da4a14..54eb541db 100644 --- a/database/sqlcipher/sqlcipher.go +++ b/database/sqlcipher/sqlcipher.go @@ -2,6 +2,7 @@ package sqlcipher import ( "database/sql" + "errors" "fmt" "io" nurl "net/url" @@ -71,11 +72,7 @@ func (m *Sqlite) ensureVersionTable() (err error) { defer func() { if e := m.Unlock(); e != nil { - if err == nil { - err = e - } else { - err = fmt.Errorf("%w: %w", err, e) - } + err = errors.Join(err, e) } }() @@ -139,11 +136,7 @@ func (m *Sqlite) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - if err == nil { - err = errClose - } else { - err = fmt.Errorf("%w: %w", err, errClose) - } + err = errors.Join(err, errClose) } }() @@ -213,7 +206,7 @@ func (m *Sqlite) executeQuery(query string) error { } if _, err := tx.Exec(query); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = fmt.Errorf("%w: %w", err, errRollback) + err = errors.Join(err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -248,7 +241,7 @@ func (m *Sqlite) SetVersion(version int, dirty bool) error { query := fmt.Sprintf(`INSERT INTO %s (version, dirty) VALUES (?, ?)`, m.config.MigrationsTable) if _, err := tx.Exec(query, version, dirty); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = fmt.Errorf("%w: %w", err, errRollback) + err = errors.Join(err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } diff --git a/database/sqlite/sqlite.go b/database/sqlite/sqlite.go index 8f1e1a590..0de03db47 100644 --- a/database/sqlite/sqlite.go +++ b/database/sqlite/sqlite.go @@ -2,6 +2,7 @@ package sqlite import ( "database/sql" + "errors" "fmt" "io" nurl "net/url" @@ -71,11 +72,7 @@ func (m *Sqlite) ensureVersionTable() (err error) { defer func() { if e := m.Unlock(); e != nil { - if err == nil { - err = e - } else { - err = fmt.Errorf("%w: %w", err, e) - } + err = errors.Join(err, e) } }() @@ -139,11 +136,7 @@ func (m *Sqlite) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - if err == nil { - err = errClose - } else { - err = fmt.Errorf("%w: %w", err, errClose) - } + err = errors.Join(err, errClose) } }() @@ -213,7 +206,7 @@ func (m *Sqlite) executeQuery(query string) error { } if _, err := tx.Exec(query); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = fmt.Errorf("%w: %w", err, errRollback) + err = errors.Join(err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -248,7 +241,7 @@ func (m *Sqlite) SetVersion(version int, dirty bool) error { query := fmt.Sprintf(`INSERT INTO %s (version, dirty) VALUES (?, ?)`, m.config.MigrationsTable) if _, err := tx.Exec(query, version, dirty); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = fmt.Errorf("%w: %w", err, errRollback) + err = errors.Join(err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } diff --git a/database/sqlite3/sqlite3.go b/database/sqlite3/sqlite3.go index 8698661de..bb24f7f7d 100644 --- a/database/sqlite3/sqlite3.go +++ b/database/sqlite3/sqlite3.go @@ -2,6 +2,7 @@ package sqlite3 import ( "database/sql" + "errors" "fmt" "io" nurl "net/url" @@ -71,11 +72,7 @@ func (m *Sqlite) ensureVersionTable() (err error) { defer func() { if e := m.Unlock(); e != nil { - if err == nil { - err = e - } else { - err = fmt.Errorf("%w: %w", err, e) - } + err = errors.Join(err, e) } }() @@ -139,11 +136,7 @@ func (m *Sqlite) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - if err == nil { - err = errClose - } else { - err = fmt.Errorf("%w: %w", err, errClose) - } + err = errors.Join(err, errClose) } }() @@ -213,7 +206,7 @@ func (m *Sqlite) executeQuery(query string) error { } if _, err := tx.Exec(query); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = fmt.Errorf("%w: %w", err, errRollback) + err = errors.Join(err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -248,7 +241,7 @@ func (m *Sqlite) SetVersion(version int, dirty bool) error { query := fmt.Sprintf(`INSERT INTO %s (version, dirty) VALUES (?, ?)`, m.config.MigrationsTable) if _, err := tx.Exec(query, version, dirty); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = fmt.Errorf("%w: %w", err, errRollback) + err = errors.Join(err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } diff --git a/database/sqlserver/sqlserver.go b/database/sqlserver/sqlserver.go index aa53a58c0..9af3a113e 100644 --- a/database/sqlserver/sqlserver.go +++ b/database/sqlserver/sqlserver.go @@ -3,6 +3,7 @@ package sqlserver import ( "context" "database/sql" + "errors" "fmt" "io" nurl "net/url" @@ -270,7 +271,7 @@ func (ss *SQLServer) SetVersion(version int, dirty bool) error { query := `TRUNCATE TABLE ` + ss.getMigrationTable() if _, err := tx.Exec(query); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = fmt.Errorf("%w: %w", err, errRollback) + err = errors.Join(err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -286,7 +287,7 @@ func (ss *SQLServer) SetVersion(version int, dirty bool) error { query = `INSERT INTO ` + ss.getMigrationTable() + ` (version, dirty) VALUES (@p1, @p2)` if _, err := tx.Exec(query, version, dirtyBit); err != nil { if errRollback := tx.Rollback(); errRollback != nil { - err = fmt.Errorf("%w: %w", err, errRollback) + err = errors.Join(err, errRollback) } return &database.Error{OrigErr: err, Query: []byte(query)} } @@ -358,11 +359,7 @@ func (ss *SQLServer) ensureVersionTable() (err error) { defer func() { if e := ss.Unlock(); e != nil { - if err == nil { - err = e - } else { - err = fmt.Errorf("%w: %w", err, e) - } + err = errors.Join(err, e) } }() diff --git a/database/yugabytedb/yugabytedb.go b/database/yugabytedb/yugabytedb.go index 3b30ce2fd..6da27cc8c 100644 --- a/database/yugabytedb/yugabytedb.go +++ b/database/yugabytedb/yugabytedb.go @@ -4,7 +4,6 @@ import ( "context" "database/sql" "errors" - "fmt" "io" "net/url" "regexp" @@ -206,11 +205,7 @@ func (c *YugabyteDB) Lock() error { } defer func() { if errClose := rows.Close(); errClose != nil { - if err == nil { - err = errClose - } else { - err = fmt.Errorf("%w: %w", err, errClose) - } + err = errors.Join(err, errClose) } }() @@ -324,11 +319,7 @@ func (c *YugabyteDB) Drop() (err error) { } defer func() { if errClose := tables.Close(); errClose != nil { - if err == nil { - err = errClose - } else { - err = fmt.Errorf("%w: %w", err, errClose) - } + err = errors.Join(err, errClose) } }() @@ -368,11 +359,7 @@ func (c *YugabyteDB) ensureVersionTable() (err error) { defer func() { if e := c.Unlock(); e != nil { - if err == nil { - err = e - } else { - err = fmt.Errorf("%w: %w", err, e) - } + err = errors.Join(err, e) } }() diff --git a/migrate.go b/migrate.go index bc1c1f867..44bfcb389 100644 --- a/migrate.go +++ b/migrate.go @@ -779,11 +779,7 @@ func (m *Migrate) versionExists(version uint) (result error) { if err == nil { defer func() { if errClose := up.Close(); errClose != nil { - if result == nil { - result = errClose - } else { - result = fmt.Errorf("%w: %w", err, errClose) - } + result = errors.Join(result, errClose) } }() } @@ -798,11 +794,7 @@ func (m *Migrate) versionExists(version uint) (result error) { if err == nil { defer func() { if errClose := down.Close(); errClose != nil { - if result == nil { - result = errClose - } else { - result = fmt.Errorf("%w: %w", err, errClose) - } + result = errors.Join(result, errClose) } }() } @@ -960,11 +952,7 @@ func (m *Migrate) unlock() error { // if a prevErr is not nil. func (m *Migrate) unlockErr(prevErr error) error { if err := m.unlock(); err != nil { - if prevErr == nil { - prevErr = err - } else { - prevErr = fmt.Errorf("%w: %w", err, prevErr) - } + prevErr = errors.Join(prevErr, err) } return prevErr } diff --git a/testing/docker.go b/testing/docker.go index 29b9dc73b..c91a1379b 100644 --- a/testing/docker.go +++ b/testing/docker.go @@ -78,11 +78,7 @@ func (d *DockerContainer) PullImage() (err error) { } defer func() { if errClose := r.Close(); errClose != nil { - if err == nil { - err = errClose - } else { - err = fmt.Errorf("%w: %w", err, errClose) - } + err = errors.Join(err, errClose) } }()