# Interfaces and error checking golang

# Introduction

In this post I would like to discuss a mistake that I have seen while I was reviewing a pull request. We are going to talk a bit about golang interfaces in the context of error handling and checking if an error is nil

## Let's see some code 

%[https://gist.github.com/gosom/30a7143de61368295a4bfc6eae413ce3]


first we define a custom error `MyError` and we implement the `error` interface.

we define 2 functions:
- `doSomething1`
- `doSomething2`

the intention of both functions is to return an error if the input value is false

Download the code and run it via `go run main.go`
Here is the output:

```
Running doSomething1(true)
        no error: <nil> <nil>
Running doSomething1(false)
        error: error happened main.MyError
Running doSomething2(true)
        error: <nil> *main.MyError
Running doSomething2(false)
        error: error happened *main.MyError

```

Let's inspect the output of `doSomething1`:
 - When the input is `true` then `err != nil` and the behavior looks correct.
 - When the input is `false` then `err==nil` and the behavior looks correct

Let's inspect the output of `doSomething2`:
 - When the input is `true` then `err == nil` and the behavior looks wrong.
 - When the input is `false` then `err!=nil` and the behavior looks correct

So something is wrong with the implementation of `doSomething2`.

## Let's investigate a bit 

```golang
func doSomething2(v bool) error {
        var err *MyError
        if !v {
                err = &MyError{}
                return err
        }
        return err
}
```

`doSomething2` returns `type error interface` and `MyError` implements thats. 


- we declare first a pointer to `MyError`  (`err` variable)
  when `v` is false we:
    - then we initialize a MyErr{} and assign it's address to err
    - we return the err 
  when `v` is true:
    - we return the err

What's the problem here?

Let's inspect the output of the `main.go` for the executions of the `doSomething2` function. 

When `v == true`:
```
Running doSomething2(true)
        error: <nil> *main.MyError
```

As you see it prints the path that is for when err != nil. 
But since we returned an uninitialized pointer of *MyError it should be nil, shouldn't be ?
 

When `v == false`
```
Running doSomething2(false)
        error: error happened *main.MyError
```
we print the path that is for when err != nil which is correct. 

Our code does not work as we expect.

## Let's see why doSomething2 is wrong

The function returns an `error` interface . 

In our main function we check if the return value of the function is nil or not. 
Since the function returns an interface we check if an interface is nil or not .

An interface consists of two parts:
- it's type 
- it's value

in  [go source code](https://github.com/golang/go/blob/master/src/runtime/runtime2.go#L202)

there is:

```
type iface struct {
	tab  *itab
	data unsafe.Pointer
}
```

`tab`: describes the interface 
`data`: it's a pointer to the value that implements the interface 

An interface is nil when both type (`tab`) and data (`data`) are nil . 
You can clearly see that this is not the case in our output:
```
<nil> *main.MyError
```
As you see the data here are nil but the type is` *main.MyError`. 

Now we have an explanation of why we see this behavior. 
Let's see how we fix now `doSomething2` .

```golang
func doSomething2(v bool) error {
        var err error
        if !v {
                err = &MyError{}
                return err
        }
        return err
}
```
We just need to use a declare a variable of type `error` and use that. 

We can also do something else in our main.go if we don't want to change our doSomething2 function
```
if err := doSomething2(true); err.(*MyError) != nil {
  ...
}
```

we convert error to the underlying type (`*MyError`) and we can check it's value. 
Do not do this! Instead always use the builtin error type to store the error values.

## Summary

An interface consists of it's underlying type and a pointer to the value that implements they interface. An interface is nil only if both the type and the value are nil. 
Be aware of that and when you return interfaces and check for nil . 
Especially in error handling use always the built in error type to store your error and return also the builtin error type. 





