Go Error Handling (Part 2) — The error Type

Sher Chowdhury
3 min readDec 28, 2020
Photo by Vitaly Sacred on Unsplash

To understand what error types are and how they work, you first need to be familiar with Go structs, methods, interfaces, and pointers.

This article is part of the Error Handling in Go series.

The error type is an interface type that comes built-in with Go.

type error interface {
Error() string
}

This essentially means that if we define a user-defined data type (i.e. a struct definition) along with a method for it called Error() (with zero input parameter and one string output parameter), then Go will treat any objects created from that struct as an object containing an error value:

Line 5: We defined a new user-defined (struct based) data type called MyError. In this example, we‘ve chosen to store a single key-value pair, with key-name of errorMsg, and data type of string.

Line 9: We defined a method for our new MyError data type. This method’s name and parameter signature matches up with the error type interface’s Error method and signature. Because of this match, Go will view MyError variables as holding information about an error.

Line 23: We created a MyError variable called.

Line 27: The fmt.Println package has done something interesting here. Under normal circumstances, you would expect it to print myError which would output the struct’s content, {network timeout} e.g. like this example. However, in this example, it actually printed the output fromMyError.Error() instead. That’s because, the fmt package also recognised that MyError is an error-object (due to lines 9–19) and so it’s trying to be more helpful and gives us the output from MyError.Error(), which is more likely what we’re interested in anyway. This behaviour is documented in the fmt package’s documentation. By the way, if we wanted to, we could have made this line more explicit, by rewriting it tofmt.Println(myErr.Error()) but the output is still the same since that is what’s implicitly implied anyway.

Now the above example is a little flawed because you can’t create a nil MyError object, since structs aren’t allowed to be nil (btw, The closest thing to a nil struct object is a zero value struct).

We can fix this by incorporating pointers into our example, so, that our objects are now pointers to MyError structs (rather than directly being MyError struct objects).

Line 11: Our Error() has now been tweaked to accepted a pointer to a MyError struct, as indicated by the *. That now means that Go considers *MyError posts as an error object.

Line 25: Since our error objects are now supposed to be pointers objects, we can now create error objects with nil values. The fmt package recognises that this is a nil error object, so it prints <nil> (line 31). It didn’t run through the error method (lines 11–21) since a nil error, means there are no errors.

Line 27: We’re now creating a new MyError object, but we’re storing the pointer to this object in myErr2, as indicated by &. This time the fmt package does apply the error method (lines 11–21) to this variable (line 32)

In the above example, we saw that before we can raise an error, we have to set up a bit scaffolding, i.e. we have to define a struct and an Error() method for that struct. However, you can bypass all that by using the errors package.

--

--