Go语言的错误处理:panic, recocer, error, error wrapping

panic和recover

panic

func panic(v interface{})
引发panic有两种情况,一种是程序主动调用panic函数(e.g. panic(xxx), panic的参数是一个空接口类型,任意类型的变量都可以传递给panic),另一种是程序产生运行时错误。
发生panic后,程序会从调用panic的函数位置或发生panic的地方立即返回,逐层向上执行函数的defer语句,然后逐层打印函数调用堆栈,直到被recover捕获或运行到最外层函数而退出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main  

import "fmt"

func tryDefer(){
for i := 0; i < 100; i++{
defer fmt.Println(i)
if i == 30 {
panic("print end")
}
}
}

func main() {
tryDefer()
}

当i循环到30时,系统会从30倒序进行Println操作,最后打印“panic: print end”。

recover

func recover() interface{}
recover用来捕获panic,阻止panic继续向上传递。recover()只有在defer后面的函数体内被直接调用才能捕获panic终止异常,否则返回nil,异常继续向外传递。

1
2
3
4
defer func(){
fmt.Println("function body")
recover()
}

记得主动在程序的中使用recover()拦截运行时错误。

error

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Package errors implements functions to manipulate errors.  
package errors

// New returns an error that formats as the given text.
func New(text string) error {
return &errorString{text}
}

// errorString is a trivial implementation of error.
type errorString struct {
s string
}

func (e *errorString) Error() string {
return e.s
}

error的底层实现非常简单,所以功能也比较弱,只能返回一个字符串。Golang 1.13中引入了一个新功能Error Wrapping。