// 我觉得这个处理挺好的
if err != nil {
return err
}
如果以标准方式处理 Go 中的错误,将获得以下好处:
panic
导致的实际程序崩溃)func f() (value, error)
的语法不仅易于向新手讲解,而且在任何 Go 项目中都可确保一致性。
注意:Go 的错误语法不会强迫处理程序可能抛出的每个错误。
Go 只是提供了一种模式,以确保你认为错误对于程序流至关重要,没有其他更多要求。
err != nil
来发现它if err := criticalDatabaseOperation(); err != nil {
// 仅仅是记录错误日志,而没有返回或停止控制流(这样不好!)
log.Printf("Something went wrong in the DB: %v", err)
// 在这一行我们应该输入`return`!
}
if err := saveUser(user); err != nil {
return fmt.Errorf("Could not save user: %w", err)
}
if err != nil
模式的优势在于,通过错误链能方便遍历程序层次结构,直到发生错误的地方。
例如,由程序的 main 函数处理的常见 Go 错误可能如下所示:
[2020-07-05-9:00] ERROR: Could not create user: could not check if user already exists in DB: could not establish database connection: no internet connection
从:
也能看出,这是四个函数调用发错误返回,可以快速定位到no internet connection
导致了这个错误的发生。
github.com/pkg/errors
提供了将堆栈跟踪附加到函数的功能。
errors.Wrap
函数返回一个新错误,这个新错误通过在调用Wrap
的点记录堆栈跟踪以及所提供的消息来将上下文添加到原始错误中。例如:
_, err := ioutil.ReadAll(r)
if err != nil {
return errors.Wrap(err, "read failed")
}
它将打印出堆栈跟踪以及您通过代码创建的易于理解的错误链。如果可以,我想总结一下我想到的有关在 Go 中编写符合
Go 习惯的错误处理的最重要建议:
当编写 Go 代码时,错误处理是永远不会担心的一件事,因为错误本身是编写的每个函数的核心内容之一,从而使我能够完全控制我如何安全,可读且负责任地处理它们。