GO错误与异常处理(精简易懂)| 青训营

81 阅读1分钟

GO错误与异常处理

错误链与Is As

不同错误之间可以进行包操作来关联,整体为一个错误链。//代码12行,错误链(err21,err1)

错误链可以及unwrap操作进行解包。退出一个错误 //代码13,错误链(err1)

链条中的每个错误都有其类型 //代码30-33

errors.Is用来判断该错误链是否包含某个错误。 //代码21-23

errors.As用来判断错误链是否包含某类型错误。 //代码26-27

package main

import (
	"fmt"
  "errors"
  "runtime/debug"
)

func main() {
  err1 := fmt.Errorf("错误%d", 404)  //普通错误,和new Error一样
  err2 := fmt.Errorf("错误%d", 404)  //即使err1一样但不是一个错误
  err21 := fmt.Errorf("包裹%w", err1) // err21包裹err1错误
  err1s := errors.Unwrap(err21)        //解包回err1
  
  fmt.Printf("类型:%T,值:%v\n", err1, err1)
  fmt.Printf("类型:%T,值:%v\n", err2, err2)
  fmt.Printf("类型:%T,值:%v\n", err21, err21)
  fmt.Printf("类型:%T,值:%v\n", err1s, err1s)
 
  //is判断错误是否包含该错误
  fmt.Println(errors.Is(err21,err1))//true
  fmt.Println(errors.Is(err21,err1s))//true
  fmt.Println(errors.Is(err21,err2))//false err2并不等于err1
  //as判断是否含有该错误类型
  err3 := errors.New("xxx") //该错误和err1都是errors.errorString类型
  fmt.Println(errors.As(err2,&err1))//true
  fmt.Println(errors.As(err2,&err3))//true
}
//返回结果
类型:*errors.errorString,值:错误404
类型:*errors.errorString,值:错误404
类型:*fmt.wrapError,值:包裹错误404
类型:*errors.errorString,值:错误404
true
true
false
true
true

panic 和recover

panic和recover要在同一个协程使用。

panic抛出的内容会被recover捕获。

panic是异常不在业务代码里使用

  //panic 触发异常(比较严重)可以被recover捕获
  //panic 和recover要在一个协程内才行。
		defer func() {
			if e := recover(); e != nil {
				// e 为 panic 返回的内容错误
				fmt.Print(
					fmt.Errorf("panic:%v\n%s", e, debug.Stack()),
				)
			}
		}()
		panic("危险")
    //下面将不会执行
    //....