勿忘初心 厚德载物

go训练营--go实践error处理

Posted on By JettyLee

Error 使用方式

Sentinel Error

预定义的特定错误

var ErrStructType = errors.New("EOF") 

自定义错误

type MyError struct{
	Msg string
	File string
	Line int
}
func (e *MyError) Error() string{
	return fmt.Sprintf("%s:%d:%s",e.File,e.Line,e.Msg)
}
func test() error{
 	return &MyError{"Something happened","server.go",42}
}

func main(){
	err:=test()
	switch err :=err.(type){
	case nil:
		//call succeeded, nothing to do
	case *MyError:
		fmt.Println("error occurred on line:",err.Line)
	default:
		// unknown error
	}
}

不透明错误

package net

type Error interface {
	error
	Timeout() bool
	Temporary() bool
}

if nerr,ok :=err.(net.Error);ok&&nerr.Temporary(){
	time.Sleep(1e9)
	continue
}

func IsTempporary(err error) bool {
	te,ok :=err.(temporary)
	return ok && te.Temporary()
}

错误处理最佳实践

第三方库的err 要用 xerrors github.com/pkg/errors
基础库禁用 wrap 要暴露原本错误
尽量做到透穿,不在业务层做判断和打log

xerrors.Wrap(err)
xerrors.Wrapf(err,"")

错误判断

  1. 利用官方库 errors.IS errors.AS
  2. 利用switch case
    switch err :=err.(type){
     case nil:
         //call succeeded, nothing to do
     case *MyError:
         fmt.Println("error occurred on line:",err.Line)
     default:
         // unknown error
    }