🤖

メモ:GORMで一意制約エラーを判別したい

2021/10/26に公開

概要

GORM[1] のエラーで ErrRecordNotFound のようにエラーが定義済のものは errors.Is() を利用して判別できるのでよいのですが、「保存時の一意制約」みたいなものは GORM でエラーが定義されてるわけではなかったりするようです。

その場合は、元になってるエラーのエラーコードを読む必要があるようです。

https://github.com/go-gorm/gorm/issues/4037#issuecomment-907863949

ちょっとハマったのでメモ。

エラーの判別

PostgresQL の場合

実際のエラーは pgconn.PgError で、この中に Code という項目がある。このコードは pgerrcode というパッケージに一覧がある。

    err := db.Create(&user).Error
	if err != nil {
        var pgErr *pgconn.PgError
        if errors.As(err, &pgErr) {
            if pgErr.Code == pgerrcode.UniqueViolation {
                return errors.New("conflict")
            }
        }
    }

MySQL の場合

こっちは実際に使ってないから分からないけど、issue にはこんなサンプルがあった。

    err := db.Create(&user).Error
    mysqlErr := err.(*mysql.MySQLError)
    switch mysqlErr.Number {
        case 1062:
            fmt.Println("Duplicate Key")
    }

Happy hacking!

脚注
  1. といっても僕が使ってるのは v1 だが ↩︎

Discussion