聊聊golang的error包装

本文主要研究一下golang的error包装

error

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

error接口定义了Error方法,返回string

runtime.Error

1
2
3
4
5
6
go复制代码package runtime

type Error interface {
error
// and perhaps other methods
}

对于panic,产生的则是runtime.Error,该接口内嵌了error接口

wrap

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
37
38
39
40
41
go复制代码package main

import (
"errors"
"fmt"

pkgerr "github.com/pkg/errors"
)

func main() {
if err := methodA(false); err != nil {
fmt.Printf("%+v", err)
}
if err := methodA(true); err != nil {
fmt.Printf("%+v", err)
}
}

func methodA(wrap bool) error {
if err := methodB(wrap); err != nil {
if wrap {
return pkgerr.Wrap(err, "methodA call methodB error")
}
return err
}
return nil
}

func methodB(wrap bool) error {
if err := methodC(); err != nil {
if wrap {
return pkgerr.Wrap(err, "methodB call methodC error")
}
return err
}
return nil
}

func methodC() error {
return errors.New("test error stack")
}

使用内置的errors,则没办法打印堆栈;使用pkg/errors可以携带堆栈

输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
go复制代码test error stack
test error stack
methodB call methodC error
main.methodB
/error-demo/error_wrap.go:33
main.methodA
/error-demo/error_wrap.go:21
main.main
/error-demo/error_wrap.go:15
runtime.main
/usr/local/go/src/runtime/proc.go:204
runtime.goexit
/usr/local/go/src/runtime/asm_amd64.s:1374
methodA call methodB error
main.methodA
/error-demo/error_wrap.go:23
main.main
/error-demo/error_wrap.go:15
runtime.main
/usr/local/go/src/runtime/proc.go:204
runtime.goexit
/usr/local/go/src/runtime/asm_amd64.s:1374%

小结

  • error接口定义了Error方法,返回string;对于panic,产生的则是runtime.Error,该接口内嵌了error接口
  • 使用内置的errors,则没办法打印堆栈;使用pkg/errors可以携带堆栈

doc

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%