Skip to content

bun: SQL based migratation will always success even WithMarkAppliedOnSuccess(true) is applied and there is SQL error #1318

@ngeojiajun

Description

@ngeojiajun

Golang version: 1.25.5
Bun version: v1.2.16
PostgreSQL version: 17

Our project is using bun's SQL-based migration and we found no matter what options we used in migrator it will always success despite the migration itself actually failed.

Here is the snippets, we have used to perform the migration:

package main

import (
	"context"
	"database/sql"
	"embed"
	"log/slog"

	"github.com/uptrace/bun"
	"github.com/uptrace/bun/dialect/pgdialect"
	"github.com/uptrace/bun/driver/pgdriver"
	"github.com/uptrace/bun/extra/bundebug"
	"github.com/uptrace/bun/migrate"
)

//go:embed *.sql
var sqlMigrations embed.FS

// List of migrations
var Migrations = migrate.NewMigrations()

func init() {
	if err := Migrations.Discover(sqlMigrations); err != nil {
		panic(err)
	}
}

func main() {
	sqldb := sql.OpenDB(pgdriver.NewConnector(pgdriver.WithDSN("postgres://postgres:@localhost:55432/postgres?sslmode=disable")))

	db := bun.NewDB(sqldb, pgdialect.New(), bun.WithDiscardUnknownColumns()).
		WithQueryHook(
			bundebug.NewQueryHook(
				bundebug.WithEnabled(true),
			),
		)

	ctx := context.Background()
	logger := slog.Default()
	migrator := migrate.NewMigrator(db,
		Migrations,
		migrate.WithMarkAppliedOnSuccess(true),
	)
	if err := migrator.Init(ctx); err != nil {
		logger.Error("Cannot initialize migration context", slog.Any("error", err))
		return
	}
	if err := migrator.Lock(ctx); err != nil {
		logger.Error("Cannot lock migration context", slog.Any("error", err))
		return
	}
	defer migrator.Unlock(ctx)
	migrations, err := migrator.Migrate(ctx)
	if err != nil {
		logger.Error("Error while performing migration", slog.Any("error", err))
		return
	}
	logger.Info("Applied migrations", slog.Any("version", migrations.Migrations.LastGroupID()))

}

Example of failed migration sql files:

-- In 03_failed_migration.up.sql
SELExc 1;

This is causing confusion, since the only way for us to know the failure is by enabling bundebug.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions