-
Book Overview & Buying
-
Table Of Contents
Mastering Go - Third Edition
By :
Go provides a special data type for representing error conditions and error messages named error—in practice, this means that Go treats errors as values. In order to program successfully in Go, you should be aware of the error conditions that might occur with the functions and methods you are using and handle them accordingly.
As you already know from the previous chapter, Go follows the next convention about error values: if the value of an error variable is nil, then there was no error. As an example, let us consider strconv.Atoi(), which is used for converting a string value into an int value (Atoi stands for ASCII to Int). As specified by its signature, strconv.Atoi() returns (int, error). Having an error value of nil means that the conversion was successful and that you can use the int value if you want. Having an error value that is not nil means that the conversion was unsuccessful and that the string input is not a valid int value.
If you want to learn more about strconv.Atoi(), you should execute go doc strconv.Atoi in your terminal window.
You might wonder what happens if you want to create your own error messages. Is this possible? Should you wish to return a custom error, you can use errors.New() from the errors package. This usually happens inside a function other than main() because main() does not return anything to any other function. Additionally, a good place to define your custom errors is inside the Go packages you create.
You will most likely work with errors in your programs without needing the functionality of the errors package. Additionally, you do not need to define custom error messages unless you are creating big applications or packages.
If you want to format your error messages in the way fmt.Printf() works, you can use the fmt.Errorf() function, which simplifies the creation of custom error messages—the fmt.Errorf() function returns an error value just like errors.New().
And now we should talk about something important: you should have a global error handling tactic in each application that should not change. In practice, this means the following:
The error data type is actually defined as an interface—interfaces are covered in Chapter 4, Reflection and Interfaces.
Type the following code in your favorite text editor and save it as error.go in the directory where you put the code for this chapter. Using ch02 as the directory name is a good idea.
package main
import (
"errors"
"fmt"
"os"
"strconv"
)
The first part is the preamble of the program—error.go uses the fmt, os, strconv, and errors packages.
// Custom error message with errors.New()
func check(a, b int) error {
if a == 0 && b == 0 {
return errors.New("this is a custom error message")
}
return nil
}
The preceding code implements a function named check() that returns an error value. If both input parameters of check() are equal to 0, the function returns a custom error message using errors.New()—otherwise it returns nil, which means that everything is OK.
// Custom error message with fmt.Errorf()
func formattedError(a, b int) error {
if a == 0 && b == 0 {
return fmt.Errorf("a %d and b %d. UserID: %d", a, b, os.Getuid())
}
return nil
}
The previous code implements formattedError(), which is a function that returns a formatted error message using fmt.Errorf(). Among other things, the error message prints the user ID of the user that executed the program with a call to os.Getuid(). When you want to create a custom error message, using fmt.Errorf() gives you more control over the output.
func main() {
err := check(0, 10)
if err == nil {
fmt.Println("check() ended normally!")
} else {
fmt.Println(err)
}
err = check(0, 0)
if err.Error() == "this is a custom error message" {
fmt.Println("Custom error detected!")
}
err = formattedError(0, 0)
if err != nil {
fmt.Println(err)
}
i, err := strconv.Atoi("-123")
if err == nil {
fmt.Println("Int value is", i)
}
i, err = strconv.Atoi("Y123")
if err != nil {
fmt.Println(err)
}
}
The previous code is the implementation of the main() function where you can see the use of the if err != nil statement multiple times as well as the use of if err == nil, which is used to make sure that everything was OK before executing the desired code.
Running error.go produces the next output:
$ go run error.go
check() ended normally!
Custom error detected!
a 0 and b 0. UserID: 501
Int value is -123
strconv.Atoi: parsing "Y123": invalid syntax
Now that you know about the error data type, how to create custom errors, and how to use error values, we'll continue with the basic data types of Go that can be logically divided into two main categories: numeric data types and non-numeric data types. Go also supports the bool data type, which can have a value of true or false only.