英文:
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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论