I have this code that works.
func (r *repoPG) WithTransaction(txFunc func() error) (err error) {
tx := db.NewTx()
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic: %v", r)
tx.Rollback()
} else if err != nil {
tx.Rollback()
} else {
tx.Commit()
}
}()
err = txFunc()
return
}
I want to avod every time to write that long defer, so I'm trying to write a func like this:
func TxDefer(tx, err) {
if r := recover(); r != nil {
err = fmt.Errorf("panic: %v", r)
tx.Rollback()
} else if err != nil {
tx.Rollback()
} else {
tx.Commit()
}
}
using it like:
func (r *repoPG) WithTransaction(txFunc func() error) (err error) {
tx := db.NewTx()
defer TxDefer(tx, err)
err = txFunc()
return
}
But this is miserably incorrect because the err it's always the original one, not the result of txFunc(), right?
How can I fix this?
Pass the address of the error to the function. This allows the function to access the current value of the caller's variable. It also allows function to set the variable.
Rollback and Commit return errors. These errors should be returned to the caller.
Use it like this:
In the code above, the expression
*perrevaluates to the current value oferrinWithTransaction. The value oferrin the question is the value oferrat the time of the defer.