When it comes to error handling in the Go programming language (Golang), they can either be incredible or a miserable nightmare in terms of management. You can choose to embrace them and check if they are nil every opportunity that you have, or you can ignore them with an underscore. However, what happens in those circumstances where you didn’t even know the function returned something?
Regardless of the story, checking for errors is a good thing, even if you hate doing it. In this tutorial we’re going to see how to scan your code for missed opportunities when it comes to error checking using a nifty open source tool.
To get an idea of what problem we’re hoping to solve, let’s take a look at the following code example:
package main
import (
"encoding/json"
"fmt"
)
type Profile struct {
Firstname string `json:"firstname"`
Lastname string `json:"lastname"`
Website string `json:"website"`
}
func main() {
nraboy := Profile{
Firstname: "Nic",
Lastname: "Raboy",
Website: "thepolyglotdeveloper.com",
}
data, _ := json.Marshal(nraboy)
fmt.Println(string(data))
json.Unmarshal(data, &nraboy)
fmt.Println(nraboy)
}
The above code does common tasks around marshalling and unmarshalling data. Both the Marshal
and Unmarshal
functions return an error, even though I’m failing to check them in my code. In one scenario I’m using an underscore, also known as a blank operator, and in the other I’m not even acknowledging that errors are a possibility.
So what can we do?
We can actually install a Go application called errcheck to scan our code for these unchecked errors so that way we can apply logic to check for them.
From the command line, execute the following:
go get -u github.com/kisielk/errcheck
If you don’t have $GOPATH/bin in your PATH, it might be a good idea to add it now, otherwise you’ll have to execute the application from the $GOPATH/bin directory every time. Not the end of the world, but in my opinion it is a hassle.
Now that we have the errcheck
application available, we can run it against our own application.
Execute the following:
errcheck .
The above command assumes that your current command line path is the path with the main.go file or whatever you’ve called your Go files. If not, just provide the path to your files instead of the period character.
When you execute the command, you’ll get a response like this:
main.go:22:16: json.Unmarshal(data, &nraboy)
The response is telling us that we’ve not checked for errors on that particular line. However, it didn’t mention our use of the underscore character from the other example.
We can fix that by executing the following:
errcheck -blank .
The above command will check for unchecked errors, including the use of the blank operator. This means that our result will look something like the following:
main.go:20:8: data, _ := json.Marshal(nraboy)
main.go:22:16: json.Unmarshal(data, &nraboy)
The errcheck
application can do other checks for us, all of which can be found in the documentation. This includes the ability to exclude certain functions from the check.
You just saw how to check for unchecked error handling within Golang applications. I actually learned about this through a colleague because they were getting frustrated with my failing to check for errors. To be clear, not because of my underscore use, but regardless all errors should be checked.
Writing code to check for errors can be a hassle in Go, but your applications will be so much better if you do.
A video version of this article can be seen below.