💻 Tech
Why does the code below fail? If checkError()
returns a nil value, then err != nil
shouldn’t be true, right? But the program exists with Failed
, so err
must not be a nil
.
Interface stores value and type. When checkError
returns a nil value of type *customErrorType
, it’s stored to variable err
of type error. This is acceptable because the custom error implements Error()
. But now, err
is no longer just containing a nil
value; it’s now an interface value holding type and value, which is not equal to a nil
value. There are two ways to remediate this:
- Change the return type of
checkError()
toerror
. This way, we’re not returning a concrete type but just a nilerror
. - Make the err in the scope of if condition like so:
err := checkError()
. This way, you’re going to check if the pointer value is nil or not.
import (
"fmt"
"log"
)
type customErrorType struct{}
func (c *customErrorType) Error() string {
return "Some error"
}
func checkError() *customErrorType {
return nil
}
func main() {
var err error
fmt.Printf("Type: %T\n", err) // <nil>
if err = checkError(); err != nil {
fmt.Printf("Type: %T\n", err) // *main.customErrorType
log.Fatal("Failed") // This is printed, then program exists
}
log.Println("Successful") // Not reached
}