本文主要介绍golang如何处理错误。
处理方法
错误码或字符串
一般是对外接口采用的方法,特别是需要序列化(如JSON)的情况。
errors package
使用 errors 包来处理错误:
- New, Errorf, Wrap, and Wrapf
生成或封装错误。
- Cause
提取封装的错误,方便后续根据具体错误类型进行处理。
%+v
或 StackTrace
打印产生错误时的栈回溯信息。
辅助类型
具体参考《Errors are values》和《Eliminate error handling by eliminating errors》。
合适的编程可以消除冗长的if err != nil
判断。
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
26
|
type errWriter struct {
w io.Writer
err error
}
func (ew *errWriter) write(buf []byte) {
if ew.err != nil {
return
}
_, ew.err = ew.w.Write(buf)
}
func writeData() error {
// ...
ew := &errWriter{w: fd}
ew.write(p0[a:b])
ew.write(p1[c:d])
ew.write(p2[e:f])
// check error in the end
if ew.err != nil {
return ew.err
}
}
|
panic+defer+recover
具体参考《The Way to Go》的处理方式,也是一种消除冗长if err != nil
判断的方法。
可以实现类似于异常处理的效果。
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
26
27
28
29
30
31
32
33
34
35
36
|
package main
import (
"fmt"
"github.com/pkg/errors"
)
func check(err error) {
if nil != err {
panic(err)
}
}
func outer() (err error) {
defer func() {
if rerr, ok := recover().(error); ok {
err = errors.Wrap(rerr, "outer")
}
}()
err = inner()
check(err)
return nil
}
func inner() error {
return errors.New("inner error")
}
func main() {
err := outer()
fmt.Printf("%v\n\n", err)
fmt.Printf("%+v\n", errors.Cause(err))
}
|
Go 2 check+handle
Go 2预计支持新的错误处理方式,感兴趣的可以先了解一下。
参考文档