GORM のエラーハンドリング
GORM のエラーハンドリングは通常の Golang と使い方が異なる。
通常の Golang の場合は以下のように関数の返り値としてエラーを取得してエラーハンドリングを行う。
err := method()
if err != nil {
errHandlingMethod()
}
GORM の場合は以下のように関数の返り値ではなく *gorm.DB の Error フィールドにエラーがセットされている。
err := db.First(&user).Error
if err != nil {
errHandlingMethod()
}
理由としては GORM の Where などの返り値が *gorm.DB になっておりチェーン可能になっているためである。
各チェーン可能なメソッドが実行されたときには *gorm.DB の AddError 関数を通して Error フィールドにエラー内容がセットされる。(Commit 、First などの関数を実行したタイミングで ErrRecordNotFound などなどがセットされる)
複数のエラーが発生することもあるため GORM にはエラーをスライスとして提供する GetErrors というメソッドが存在する。
またエラーの中でも DB を検索した場合に検索条件に該当するレコードが存在しない場合のエラーとして ErrRecordNotFound が定義されている。
ErrRecordNotFound は GORM の errors.go で errors.New("record not found") として定義されているため Golang の errors が元になっている。
RecordNotFound メソッドはセットされている Error の中に ErrRecordNotFound が存在するかを判定し返り値として bool を返す関数である。bool を返すため if 文の条件部分に使用することができる。
if db.First(&user, 1).RecordNotFound() {
// レコードが見つからない場合のエラーハンドリング
}
すべてのエラーを取り出しその中に RecordNotFound があるかの確認は以下。
if err := db.First(&user, 1).Error; gorm.IsRecordNotFound(err) {
// レコードが見つからない場合のエラーハンドリング
}