如何使用GORM检查CRUD操作中的错误?

blz*_*blz 16 go go-gorm

GORM 的官方文档演示了一种可以测试记录是否存在的方法,即:

user := User{Name: "Jinzhu", Age: 18, Birthday: time.Now()}

// returns true if record hasn’t been saved (primary key `Id` is blank)
db.NewRecord(user) // => true

db.Create(&user)

// will return false after `user` created
db.NewRecord(user) // => false
Run Code Online (Sandbox Code Playgroud)

这可用于间接测试记录创建中的错误,但在发生故障时不报告任何有用信息.

检查了源代码后db.Create,似乎有某种堆栈帧检查在继续之前检查错误,这意味着事务错误将无提示失败:

func Create(scope *Scope) {
    defer scope.Trace(NowFunc())

    if !scope.HasError() {
        // actually perform the transaction
    }
}
Run Code Online (Sandbox Code Playgroud)
  • 这是一个错误,还是我错过了什么?
  • 我怎么能/应该被告知交易失败?
  • 我在哪里可以获得有用的调试信息?

icz*_*cza 20

DB.Create()返回一个新的(克隆的)gorm.DB,它是一个struct并且有一个字段Error:

type DB struct {
    Value        interface{}
    Error        error
    RowsAffected int64
    // contains filtered or unexported fields
}
Run Code Online (Sandbox Code Playgroud)

您可以存储返回的*gorm.DB值并检查其DB.Error字段,如下所示:

if dbc := db.Create(&user); dbc.Error != nil {
    // Create failed, do something e.g. return, panic etc.
    return
}
Run Code Online (Sandbox Code Playgroud)

如果您不需要返回任何其他内容gorm.DB,您可以直接检查其Error字段:

if db.Create(&user).Error != nil {
    // Create failed, do something e.g. return, panic etc.
    return
}
Run Code Online (Sandbox Code Playgroud)

  • 此错误检查至少在当前gorm中不起作用.请参阅@windyzboy的回答和我在那里的评论. (3认同)

win*_*boy 13

我已经尝试了接受的答案,但它不起作用,db.Error总是返回nil.

只是改变一些东西,它的工作原理,希望它有助于某人:

if err := db.Create(&Animal{Name: "Giraffe"}).Error; err != nil {
   // Create failed, do something e.g. return, panic etc.
   return 
}
Run Code Online (Sandbox Code Playgroud)

  • 正确.接受的答案不起作用,因为`Create`返回`DB`的克隆,并且在该克隆中设置`Error`字段而不是原始对象. (4认同)