golang 的错误处理,我之前也吐槽,但从 1.13 开始吧就挺好用了。 之前吐槽点:
现在已经不是问题了。
// LineInfo 返回调用此函数的代码所在函数、文件、行号
// 此函数应该在一个单独的文件中,比如,utils/getlineinfo.go
func LineInfo() string {
function := "xxx"
pc, file, line, ok := runtime.Caller(1)
if !ok {
file = "???"
line = 0
}
function = runtime.FuncForPC(pc).Name()
return fmt.Sprintf(" -> %s():%s:%d", function, file, line)
}
var ErrAuth = errors.New("auth error")
var ErrAccount = fmt.Errorf("%w: account not exist", ErrAuth)
var ErrPassword = fmt.Errorf("%w: incorrect password", ErrAuth)
func login(acc, pwd string) (string, error) {
if acc != "libai" {
return "", ErrAccount
}
if pwd != "123456" {
return "", ErrPassword
}
return fmt.Sprintf("key:AC34cvG-%d", time.Now().Unix()), nil
}
func getInfo(acc, pwd string) (string, error) {
key, err := login(acc, pwd)
if err != nil { // login 的错误
return "", fmt.Errorf("%w%s", err, LineInfo())
}
// 打开下面的注释就会是 key 过期
//time.Sleep(time.Second)
msg, err := getIntro(key)
if err != nil { // key 错误
return "", fmt.Errorf("%w%s", err, LineInfo())
}
return msg, nil
}
var ErrKey = errors.New("invalid key")
func getIntro(key string) (string, error) {
if key != fmt.Sprintf("key:AC34cvG-%d", time.Now().Unix()) {
return "", ErrKey
}
return "李白,号青莲居士", nil
}
func main() {
info, err := getInfo("libai", "123456")
if err != nil && errors.Is(err, ErrAuth) { // 无论账号错误还是密码错误,都是认证错误
fmt.Printf("[info]%s\n", err.Error())
} else if err != nil {
fmt.Printf("[error]:%s\n", err.Error())
}
fmt.Println(info)
}
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.