0%

Golang中错误处理之坑


在编程中,我们很多时候需要自定义错误处理。但是由于go本身的一些语法特性,存在着一个问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
type MyError struct {
msg string // 错误描述
Offset int64 // 错误发生的位置
}

func (e *MyError) Error() string {
return e.msg
}

func noThorwError() error {
var err *MyError
if 1 == 2 {
err = &MyError{msg: "错误", Offset: 12}
}
return err
}

func main() {
err := noThorwError()
// 这里始终是true
if err != nil {
fmt.Println("发生异常")
}
}

上面的代码,调用noThorwError() 始终引发异常,究其原因,是因为在golang中,interface{}类型实

际上由(T,V)两部分构成,直接调用nil进行判断时,T==MyError 而不是nil引发。

这块可以参考:https://go.dev/doc/faq#nil_error

具体解决办法如下:

  1. 错误类型仅对包内可见 只对外暴露构造方法 这样可以避免在方法申明中被使用
  2. 方法申明中错误类型使用error
  3. 方法内部不通过var err *myError这种方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 错误类型仅对包内可见 只对外暴露构造方法 这样可以避免在方法申明中被使用
type myError struct {
msg string // 错误描述
Offset int64 // 错误发生的位置
}

func (e *myError) Error() string {
return e.msg
}

// 函数返回值类型申明为error
func noThorwError() error {
if 1 == 2 {
return getErr
}
return nil
}

func main() {
err := noThorwError()
if err != nil {
fmt.Println("发生异常")
}
fmt.Println(reflect.TypeOf(err))
}