Go does not have try/catch or try/except. Instead almost every function returns (or should return) an error value. It's good practice to return an error value in every function and also check it after reading values from functions/channels/etc. As a result it's very common to see if err != nil
code blocks.
Go's error handling is very controversial. Some call it genius and others not so much. For more information read the Error handling and Go blog.
error
type is similar to Stringer()
.
type error interface {
Error() string
}
Create a method for the struct type named Error()
to return error codes/messages.
func (e MyType) Error() string {
return fmt.Sprintf("error message")
}
According to Go docs, errors strings should not be capitalized. Most built-in and package methods return an error value if an error occurs, otherwise they will return nil
for error which means no error.
Checking for errors after every function call will result in a lot of if err != nil
blocks. One good way is to create a function to check the error and perform actions based on it. For example:
func checkError(err) {
if err != nil {
// Do something
}
}
The errors exercise is part of tour of go.
// 02.7-01-errors1.go
package main
import (
"fmt"
"math"
)
type ErrNegativeSqrt float64
func (e ErrNegativeSqrt) Error() string {
return fmt.Sprintf("cannot Sqrt negative number: %v", float64(e))
}
func Sqrt(x float64) (float64, error) {
if x < 0 {
return 0, ErrNegativeSqrt(x)
}
// Don't need else here - why?
return math.Sqrt(x), nil
}
func main() {
fmt.Println(Sqrt(2))
fmt.Println(Sqrt(-2))
}
Instead of creating an Error()
method, we could create a new error type and return that using fmt.Errorf
:
// 02.7-02-errors2.go
package main
import (
"fmt"
"math"
)
func Sqrt(x float64) (float64, error) {
if x < 0 {
return 0, fmt.Errorf("cannot Sqrt negative number: %v", float64(x))
}
return math.Sqrt(x), nil
}
func main() {
fmt.Println(Sqrt(2))
fmt.Println(Sqrt(-2))
}