In the previous post, we talked about handle errors in Golang. In this tutorial, we will provide some examples of defining errors using New()
function:
errors
: Package errors implements functions to manipulate errors. The New function creates errors whose only content is a text message.
Method-1: Using errors.New to declare new error in GO
Example 1: Simple use of errors.New() function to return a new error
func New(text string) error
: New returns an error that formats as the given text. Each call to New returns a distinct error value even if the text is identical.
Here is an example of using errors.New()
in Go:
package main
import (
"errors"
"fmt"
)
func main() {
err := errors.New("This is a new error!")
if err != nil {
fmt.Print(err)
}
}
Example 2: More complex use of errors.New() to return new error
Here is an example of checking a string begins with 'S' or not. If invalid, return an error:
package main
// import the errors package
import (
"errors"
"fmt"
"strings"
)
// check if string starts with S
func checkStartWith(str string) error {
// create a new error
newError := errors.New("Invalid String")
if !(strings.HasPrefix(str, "S") || strings.HasPrefix(str, "s")) {
return newError
}
// return nil if there is no error
return nil
}
func main() {
str1 := "Hello"
str2 := "Sorry"
// call the function
err1 := checkStartWith(str1)
// check if the err is nil or not
if err1 != nil {
fmt.Println(err1)
} else {
fmt.Println("Valid String")
}
err2 := checkStartWith(str2)
// check if the err is nil or not
if err2 != nil {
fmt.Println(err2)
} else {
fmt.Println("Valid String")
}
}
Output:
Invalid String
Valid String
Method-2: Using Errorf() with fmt package to return an error
func Errorf(format string, a ...any) error
: Errorf formats according to a format specifier and returns the string as a value that satisfies error. If the format specifier includes a %w verb with an error operand, the returned error will implement an Unwrap method returning the operand.
The example below shown how to use Errorf()
function to return an error. We create a map which key is the id, then we check if id 17 is in the map. If not, raise an error:
package main
import (
"fmt"
)
func main() {
const name, id = "Daniel", 17
listId := map[int]string{1: "Anna", 2: "Bob", 5: "Harry", 7: "Chris", 8:"Cody", 18: "Ron"}
if _, ok := listId[17]; !ok {
err := fmt.Errorf("user %q (id %d) not found", name, id)
fmt.Println(err.Error())
}
}
Output:
user "Daniel" (id 17) not found
Method-3: Define a custom error type with interface
You have to satisfy the predeclared error interface in order to define a custom error type:
type error interface {
Error() string
}
We will write a function to divide 2 positive integers. If one of the input is negative integer, raise an InvalidParam error; if DivisionByZero raise an DivisionByZero error:
package main
import "fmt"
type error interface {
Error() string
}
type DivisionByZero struct {
message string
}
type InvalidParam struct {
message string
}
// define Error() method on the struct
func (e *DivisionByZero) Error() string {
return "Number Cannot Be Divided by Zero"
}
// define Error() method on the struct
func (e *InvalidParam) Error() string {
return "Numbers must be positive integers"
}
func dividePosInt(n1 int, n2 int) (int, error) {
if (n1<0 || n2< 0) {
return 0, &InvalidParam{}
} else if n2 == 0 {
return 0, &DivisionByZero{}
} else {
return n1 / n2, nil
}
}
func main() {
x1 := 20
x2 := 0
result, err := dividePosInt(x1, x2)
// check if error occur or not
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("Result: %d", result)
}
y1 := -2
y2 := 0
result2, err := dividePosInt(y1, y2)
// check if error occur or not
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("Result: %d", result2)
}
}
Output:
Number Cannot Be Divided by Zero
Number must be positive integers
Summary
A strong piece of code must be capable of handling faults. I have shown you some ways to return an error and then handle it in the caller. You can use errors.New()
functions or implement your own interface to handle errors in your program.
References
https://go.dev/doc/tutorial/handle-errors
https://pkg.go.dev/errors
https://pkg.go.dev/fmt