你可以使用GORM来检查CRUD操作中的错误。

huangapple go评论86阅读模式
英文:

How can I check for errors in CRUD operations using GORM?

问题

GORM的官方文档演示了一种检测记录存在性的方法,例如:

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

// 如果记录尚未保存(主键`Id`为空),返回true
db.NewRecord(user) // => true

db.Create(&user)

// 在`user`创建后将返回false
db.NewRecord(user) // => false

这可以用于间接测试记录创建中的错误,但在失败的情况下不提供有用的信息。

通过检查db.Create的源代码,似乎有一种堆栈帧检查错误的方式,然后再继续执行,这意味着事务错误将会静默失败:

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

    if !scope.HasError() {
        // 执行事务
    }
}
  • 这是一个bug还是我漏掉了什么?
  • 我应该如何被告知事务失败?
  • 我可以在哪里获取有用的调试信息?
英文:

The official documentation for GORM demonstrates a way in which one can test for the existence of a record, i.e.:

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

This can be used to test indirectly for errors in record creation but reports no useful information in the event of a failure.

Having checked the source code for db.Create, there seems to be some sort of stack-frame inspection that checks for errors before proceeding, meaning that transactional errors will fail silently:

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

	if !scope.HasError() {
        // actually perform the transaction
    }
}
  • Is this a bug, or am I missing something?
  • How can/should I be informed of a failed transaction?
  • Where can I get useful debugging information?

答案1

得分: 30

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

type DB struct {
    Value        interface{}
    Error        error
    RowsAffected int64
    // 包含被过滤或未导出的字段
}

你可以存储返回的 *gorm.DB 值,并像这样检查它的 DB.Error 字段:

if dbc := db.Create(&user); dbc.Error != nil {
    // 创建失败,做一些操作,比如返回、抛出异常等等
    return
}

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

if db.Create(&user).Error != nil {
    // 创建失败,做一些操作,比如返回、抛出异常等等
    return
}
英文:

DB.Create() returns a new (cloned) gorm.DB which is a struct and has a field Error:

type DB struct {
    Value        interface{}
    Error        error
    RowsAffected int64
    // contains filtered or unexported fields
}

You can store the returned *gorm.DB value and check its DB.Error field like this:

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

If you don't need anything else from the returned gorm.DB, you can directly check its Error field:

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

答案2

得分: 19

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

只需做一些更改,它就能正常工作,希望对某人有帮助:

if err := db.Create(&Animal{Name: "Giraffe"}).Error; err != nil {
   // 创建失败,做一些操作,比如返回、抛出异常等。
   return 
}
英文:

I have tried the accepted answer, but it doesn't work, db.Error always return nil.

Just change something and it works, hope it helps somebody:

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

答案3

得分: 0

如果你想检查错误类型,就这样做。

if err := db.Create(&user).Error; err != nil {

  if errors.Is(err, gorm.ErrRecordNotFound) {
    fmt.Println(err.Error())
  }

  return

}
英文:

If you want to check type of error, just do it.

if err := db.Create(&user).Error; err != nil {

  if errors.Is(err, gorm.ErrRecordNotFound) {
    fmt.Println(err.Error())
  }

  return

}

huangapple
  • 本文由 发表于 2015年5月21日 06:47:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/30361671.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定