A couple of weeks ago I went to the Go London User Group and one of the talks was about error handling in Go by Daniel Morsing (really good talk).
After thinking, I rembembered that there is another antipattern when using pointers to error, for example here.
// http://play.golang.org/p/Xktu2Jz-Zc
package main
import "fmt"
type MyError struct {
path string
msg string
}
func (e MyError) Error() string {
return e.path + ":" + e.msg
}
func uglyBug(blowup bool) error {
var err *MyError = nil
if blowup {
err = &MyError{"path1", "msg1"}
}
return err
}
func main() {
e1 := uglyBug(false)
if e1 != nil {
fmt.Println("Pointer -> ", e1)
} else {
fmt.Println("It's ok")
}
}
Output:
Pointer -> <nil>
The value of e1 is going to be not nil, because the interface is not nil (it needs to have the value and the type nil, to return nil).
To fix this, you have to explicit return nil.
package main
import "fmt"
type MyError struct {
path string
msg string
}
func (e MyError) Error() string {
return e.path + ":" + e.msg
}
func fixed(blowup bool) error {
if blowup {
return &MyError{"path1", "msg1"}
}
return nil
}
func main() {
e1 := fixed(false)
if e1 != nil {
fmt.Println("Pointer -> ", e1)
} else {
fmt.Println("It's ok")
}
}
Output:
It's ok
So always do a explicit return nil, when you need an interface to be nil.