When Golang nil is not nil

Custom error type in Golang

is very common when one want to do some serious programming.

The obvious reason would be gaining ability to wrap one error with another or provding additional context for easier tracing.

Defining one would also be easy as long as your type defined an Error() public method returning string.

Then one would simply rely on Golang error interface mechanism to work its magic(implied).

However you figured nil is not really nil(of the type you think)

when your custom error indeed is nil.

This happens when you use a pointer to your own error type in the place of the built in error type.

Take following program for example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package main
import "fmt"
type Error struct {
Detail string
OriginalError error
}
func (e *Error) Error() string {
return fmt.Sprintf("error: %s, detail: %s", e.OriginalError, e.Detail)
}
func ReturnCustomErrorType() (err *Error) {
return
}
func ReturnErrorAsWrongType() (err error) {
// This is where the evil things happening
err = ReturnCustomErrorType()
return
}
func main() {
err := ReturnErrorAsWrongType()
if err != nil {
fmt.Printf("Found error %v\n", err)
} else {
fmt.Println("No Errors")
}
}

The above program will output:

1
Found error <nil>

This is because the err is considered error type, when comparing to nil in statement if err != nil Golang will compare not only the value but also the type, since the left hand side of the equition is a nil pointer pointing to custom Error type they are considered unequal.

Now you learn one more thing to hate about Golang type system, please enjoy rest of your day.