前言
Go语言检测和报告错误情况的常用方法:
函数返回的多个值,并按照惯例将最后一个值定位错误。if条件判断这个错误值,如果为nil,则没有错误。
例子
package main
import (
"fmt"
"time"
"errors"
// "os"
)
type Employee struct {
ID int
FirstName string
LastName string
Address string
}
var ErrNotFound = errors.New("Employee not found")
func main() {
employee, err := getInformation(1001)
if err != nil {
fmt.Printf("%v", err)
// Something is wrong. Do something.
} else {
fmt.Print(employee)
}
}
func getInformation(id int) (*Employee, error) {
for tries := 0; tries < 3; tries++ {
employee, err := apiCallEmployee(1000)
if err == nil {
return employee, nil
}
fmt.Printf("Server is not responding, retrying...\n%v\n", err)
time.Sleep(time.Second * 2)
}
return nil, fmt.Errorf("server has failed to respond to get the employee infotmation")
}
func apiCallEmployee(id int) (*Employee, error) {
if id != 1001 {
return nil, ErrNotFound
}
employee := Employee{LastName: "Doe", FirstName: "John"}
return &employee, nil
}
常见的一些写法
fmt.Errorf("Got an error when getting the employee information: %v", err)
errors.New('string')
这两种写法的区别,就是fmt.Errorf()支持格式化,errors.New()可以用来创建错误变量从而重复利用。
var ErrNotFound = errors.New("Employee not found!")
ErrNotFound变量中Err前缀是错误变量常用的惯例写法。
if errors.Is(err, ErrNotFound) {
fmt.Printf("Not Fount: %v\n", err)
} else {
fmt.Print(employee)
}
返回 true/false 用来判断比较错误变量。其中 ErrNotFound 是提前定义好的错误,err是需要比对的错误
推荐的错误用法
- 始终检查是否存在错误,即使预期不存在。 然后正确处理它们,以免向最终用户公开不必要的信息。
- 在错误消息中包含一个前缀,以便了解错误的来源。 例如,可以包含包和函数的名称。
- 创建尽可能多的可重用错误变量。
- 了解使用返回错误和 panic 之间的差异。 不能执行其他操作时再使用 panic。 例如,如果某个依赖项未准备就绪,则程序运行无意义(除非你想要运行默认行为)。
- 在记录错误时记录尽可能多的详细信息(我们将在下一部分介绍记录方法),并打印出最终用户能够理解的错误。