go语言中处理错误的五种策略
Posted jun10ng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了go语言中处理错误的五种策略相关的知识,希望对你有一定的参考价值。
本文只是简单的介绍了五种错误处理策略,对于如何更优雅的处理错误,可以翻看我往期的文章。
go之父谈error
go 1.13的错误处理
错误处理策略
-
传播错误
这意味着函数中某个子程序的失败,会变成该函数的失败。把流程中某个子函数的错误“传播”给主流程函数,并中断。
res, err := subFunc(arg) if err != nil{ return nil, err }
这样的错误返回也可以包装下
if err != nil { return nil, fmt.Errorf(" %s : %v", arg,err) }
可以额外了解下 go 1.14的 unwarp error 和 %w 占位符。这样使用传播错误可以使错误信息模拟调用过程,呈链式。当错误最终由main函数处理时,错误信息应提供清晰的从原因到后果的因果链。由于错误信息经常是以链式组合在一起的,所以错误信息中应避免大写和换行符。最终的错误信息可能很长,我们可以通过类似grep的工具处理错误信息(译者注:grep是一种文本搜索工具)。
-
重试
如果错误的发生时偶然性的(类似TCP的部分错误处理),那么我们可以采用重试的策略,但是要注意重试的时间和次数,防止无限制的重试。在所有重试之后如果还是失败的话,再返回错误。
// WaitForServer 尝试连接url参数对应的服务器 // 它持续一分钟的重连,并采用指数级的等待时间增加 // 如果所有重试都失败了,将返回错误 func WaitForServer(url string) error { const timeout = 1 * time.Minute deadline := time.Now().Add(timeout) for tries := 0; time.Now().Before(deadline); tries++ { _, err := http.Head(url) if err == nil { return nil // success } log.Printf("server not responding (%s);retrying…", err) time.Sleep(time.Second << uint(tries)) // 指数递增 } return fmt.Errorf("server %s failed to respond after %s", url, timeout) }
-
第一时间结束
这个策略一般用在 main 文件中,当主流程遇到错误时,直接退出结束程序。
这个策略一般与 错误传播 策略合用,将子函数传播至主流程中,然后依照错误的严重性判断是否结束程序。
// 在主程序中 if err := WaitForServer(url); err != nil { log.Fatalf("wrong %v ",err) os.Exit(1) }
-
只输出错误信息,不中断
就是调用日志系统,常见于一些小问题,如图片丢失等。
-
忽略错误
dir, err := ioutil.TempDir("", "scratch")
if err != nil {
return fmt.Errorf("failed to create temp dir: %v",err)
}
// ...use temp dir…
os.RemoveAll(dir) // ignore errors; $TMPDIR is cleaned periodically
尽管os.RemoveAll会失败,但上面的例子并没有做错误处理。这是因为操作系统会定期的清理临时目录。正因如此,虽然程序没有处理错误,但程序的逻辑不会因此受到影响。我们应该在每次函数调用后,都养成考虑错误处理的习惯,当你决定忽略某个错误时,你应该清晰地写下你的意图。
以上是关于go语言中处理错误的五种策略的主要内容,如果未能解决你的问题,请参考以下文章