• GO错误处理方式


    Go 的错误处理和其他主流的编程语言如 Java、C# 等不同:

    • Go 内置错误不包含堆栈跟踪
    • 没有异常,只有错误
    • 不支持 try/catch 方式捕获

    错误类型

    Go 中的错误类型实现为如下接口:

    1. type error interface {
    2. Error() string
    3. }
    4. 复制代码

    所以,Go 的错误类型就这么简单,只要是任何实现 Error() 方法的东西,返回信息是字符串类型即可。

    那么,我们可以轻松自定义错误,可以通过两种方式构建错误:

    1、Go 的内置错误 errors

    2、 fmt 包即时构建错误,将错误信息输出

    实现 Demo 如下

    自定义错误机制

    1. package main
    2. func customErr() error {
    3. return errors.New("server not work")
    4. }
    5. func customErr2() error {
    6. host := "http://localhost:2033"
    7. fmt.Errorf("server %s set up fail", host)
    8. }
    9. 复制代码

    最佳处理错误方式

    所以,在处理错误时通过判断 err 参数来处理错误:

    1. result, err := doHandler()
    2. if err != nil {
    3. // handle error
    4. }
    5. 复制代码

    当处理比较多业务逻辑时,可能调用很多方法,这时就会处理一大堆的 err,如下所示:

    1. func doHandler(){
    2. res, err := getA()
    3. if err!=nil {
    4. // handle getA error
    5. }
    6. err := getB()
    7. if err!=nil {
    8. // handle getB error
    9. }
    10. err := getc()
    11. if err!=nil {
    12. // handle getc error
    13. }
    14. }
    15. 复制代码

    每个方法都需要判断 error 。可能会觉得上述代码不够优雅且浪费代码,但这就是 Go 的代码。

    预定义错误

    Go 中对预期内的错误,定义相对的错误处理,这样方便在代码的其他部分显式的检查他们,遇到这种错误只需要执行不同的代码分支即可。

    1. var
    2. NotFoundError = errors.New("未找到参数")
    3. ForbiddenError = errors.New("权限不足")
    4. func doHandler(){
    5. if userId == ''{
    6. return NotFoundError
    7. }
    8. }
    9. 复制代码

    预定义错误,只能处理自己定义该类型的错误场景。且在使用时,必须通过和预期的值进行比较判断。这种关联性太强,局限性太大。

    自定义错误类型

    返回错误时,可能需要携带额外的错误字段或者其他的错误信息,而不是单独的返回错误字符串。通过自定义错误类型,可以让我们错误信息包含更多的信息。

    1. type CustomError struct {
    2. UserId string
    3. Message string
    4. }
    5. func (e * CustomError) Error() string{
    6. return fmt.Sprintf("%s : %s", e.UserId, e.Msg)
    7. }
    8. 复制代码

    CustomError 实现了 Error 接口,我们可以使用 error.As 或者使用类型断言(err.(type)) 来检查标准错误并将其转换为更具体的错误。

    和预定义错误相比,自定义错误能够包装底层错误以提供更多的上下文,但是同样会将错误类型暴露出去。

    不透明错误

    前面2种会暴露错误类型给外部,所以可以将通过提供给不公开的接口,仅暴露具体的错误方法,

    1. type serverError interface {
    2. default() bool
    3. }
    4. func NotFoundError(err error) bool {
    5. m,ok := err.(serverError)
    6. return ok && m.default()
    7. }
    8. 复制代码

    以上只提供具体错误方法,返回错误,暴露错误判定接口,不返回类型。通过断言错误实现特定的行为,而不是断言错误是特定的类型或值。这种错误处理方式相对于灵活。


    作者:六号积极分子
    链接:https://juejin.cn/post/7123843734717857828
    来源:稀土掘金
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 相关阅读:
    开发前期准备工作
    协议的定制之序列化与反序列化 | 守护进程
    微服务实战 07Spring Cloud Gateway 入门与实战
    .net core微服务之服务发现
    MySQL的 validate_password插件 和 validate_password组件
    【计算机视觉 | 目标检测】arxiv 计算机视觉关于目标检测的学术速递(6月 23 日论文合集)
    【计算机毕业设计】网上游戏代练商城系统
    MyBatis
    Webpack 5 超详细解读(三)
    3分钟教你StudioOne6下载安装与激活教程
  • 原文地址:https://blog.csdn.net/dj1540225203/article/details/126056055