GO错误处理方式

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

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

错误类型

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

type error interface {
    Error() string
}
复制代码

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

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

1、Go 的内置错误 errors

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

实现 Demo 如下

自定义错误机制

package main

func customErr() error {
    return errors.New("server not work")
}

func customErr2() error {
    host := "http://localhost:2033"
    fmt.Errorf("server %s set up fail", host)
}
复制代码

最佳处理错误方式

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

result, err := doHandler()
if err != nil {
    // handle error
}
复制代码

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

func doHandler(){
    res, err := getA()
    if err!=nil {
        // handle getA error
     }
    err := getB()
    if err!=nil {
         // handle getB error
     }
    err := getc()
    if err!=nil {
         // handle getc error
     }
}
复制代码

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

预定义错误

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

var ( 
   NotFoundError = errors.New("未找到参数")
   ForbiddenError = errors.New("权限不足")
)


func doHandler(){
    if userId == ''{
        return NotFoundError
    }
}
复制代码

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

自定义错误类型

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

type CustomError struct {
    UserId string
    Message string
}

func (e * CustomError) Error() string{
    return fmt.Sprintf("%s : %s", e.UserId, e.Msg)
}
复制代码

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

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

不透明错误

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

type serverError interface {
    default() bool
}
func NotFoundError(err error) bool {
    m,ok := err.(serverError)
    return ok && m.default()
}
复制代码

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


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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值