[Awesome Go] Errors handling before Go 1.13 - errors - Programming Language - Golang (Go) - Exception Error Handling

error

In error handling in the Go language, errors are an important part of the software package API and application user interface. Errors are returned as a normal return value.

In this article, we are going to explore error handling before Go 1.13.

error is a built-in type in Go.

1
2
3
type error interface {
Error() string
}

An idiomatic way to handle an error is to return it as the last return value of a function call and check for the nil condition.

1
2
3
4
5
6
val, err := myFunction( args... );
if err != nil {
// handle error
} else {
// success
}

errors.new(string) error

errors.New constructs a basic error value with the given error message.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package main

import (
"errors"
"fmt"
)

func f1(arg int) (int, error) {
if arg == 42 {

return -1, errors.New("can't work with 42")
}

// A nil value in the error position indicates that there was no error.
return arg + 3, nil
}

func main() {
if r, e := f1(42); e != nil {
fmt.Println("f1 failed:", e)
} else {
fmt.Println("f1 worked:", r)
}
}

if r, e = f1(43); e != nil {
fmt.Println("f1 failed:", e)
} else {
fmt.Println("f1 worked:", r)
}
}
}

Run main.go.

1
2
3
$ go run main.go
f1 failed:can't work with 42
f1 worked:

fmt.Errorf(string, …interface{}) error

The fmt.Errorf() function in Go language allow us use formatting features to create descriptive error messages.

It will format an string and return an error by call errors.new(string).

1
func Errorf(format string, a ...interface{}) error

Example main.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Golang program to illustrate the usage of 
// fmt.Errorf() function

// Including the main package
package main

// Importing fmt and time
import (
"fmt"
"time"
)

// Calling main
func main() {

// Calling Errorf() function with verb $v which is used
// for printing structs
err := fmt.Errorf("error occurred at: %v", time.Now())

// Printing the error
fmt.Println("An error happened:", err)

newErr := fmt.Errorf("A new error occurred at: %v", err)

// Printing the new error
fmt.Println("A new error happened:", newErr)
}

Run main.go.

1
2
3
$ go run main.go
An error happened: error occurred at: 2009-11-10 23:00:00 +0000 UTC m=+0.000000001
A new error happened: A new error occurred at: error occurred at: 2009-11-10 23:00:00 +0000 UTC m=+0.000000001

Through the fmt.Errorf function, a new err is generated based on the existing err, and then the text information we want to add is appended. This method is more convenient, but the problem is also obvious, we lost the original err information.

Custom Error

We can customize our own error struct and add fields for storing additional error information we need.

In Go language, any type that implements the error interface is as an error. So, let’s create our first error by implementing error interface.

Example: main.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package main

import "fmt"

// create a struct
type MyError struct{}

// struct implements `Error` method
func (myErr *MyError) Error() string {
return "Something unexpected happend!"
}

func main() {

// create error
myErr := &MyError{}

// print error message
fmt.Println(myErr)
}

Run main.go.

1
2
$ go run main.go
Something unexpected happend!

An error value may be of any type which satisfies the language-defined error interface. A program can use a type assertion (interface{}) (error, bool) or type switch target_type(interface{}) to view an error value as a more specific type.

1
2
3
4
5
6
7
8
9
10
11
12
type NotFoundError struct {
Name string
}

func (e *NotFoundError) Error() string { return e.Name + ": not found" }

if e, ok := err.(*NotFoundError); ok {
// // e.Name wasn't found

// convert to NotFoundError explictly
notFoundError = NotFoundError(err)
}

References

[1] Working with Errors in Go 1.13 - The Go Blog - https://blog.golang.org/go1.13-errors

[2] Error handling in Go. Go does not provide conventional… | by Uday Hiwarale | RunGo | Medium - https://medium.com/rungo/error-handling-in-go-f0125de052f0

[3] fmt.Errorf() Function in Golang With Examples - GeeksforGeeks -https://www.geeksforgeeks.org/fmt-errorf-function-in-golang-with-examples/

[4] Go by Example: Errors - https://gobyexample.com/errors

[5] The Go Programming Language - https://golang.org/