Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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?
like image 407
Louis Thibault Avatar asked May 20 '15 22:05

Louis Thibault


People also ask

How do you log a Gorm query?

Current state of logging in GORM In order to enable logging for all queries, we need to invoke the LogMode method with true as the argument. The logs below are for a simple /GET API call which retrieves records from the orders and items table.

What is Tx in Gorm?

GORM supports nested transactions, you can rollback a subset of operations performed within the scope of a larger transaction, for example: db.Transaction(func(tx *gorm.DB) error { tx.Create(&user1)

What is err in Golang?

If you have written any Go code you have probably encountered the built-in error type. Go code uses error values to indicate an abnormal state. For example, the os. Open function returns a non-nil error value when it fails to open a file. func Open(name string) (file *File, err error)


2 Answers

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 } 
like image 171
icza Avatar answered Oct 10 '22 08:10

icza


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  } 
like image 26
windyzboy Avatar answered Oct 10 '22 09:10

windyzboy