一. error接口的定义

:就一个Error方法,返回字符串

type error interface {
   Error() string
}

二. errors包

package errors

// 即便文本一样,返回的是独一份的
func New(text string) error {
   return &errorString{text}
}

// errorString 一个简易的error接口的实现结构体
type errorString struct {
   s string
}

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

三个重要的方法

func Unwrap(err error) error                 // 获得err包含下一层错误
func Is(err, target error) bool              // 判断err是否包含target
func As(err error, target interface{}) bool  // 判断err是否为target类型

三、判断error的类型

3.1 简单的方式:和低级语言一样的方式.

var   ErrInvalidParam = errors.New("invalid param")

if err != nil && err == ErrInvalidParam {
   //...
}

if err != nil {
        switch err {
        case ErrInvalidParam:
                //..
          return
        case ErrNetWork:
                //...
          return
        case ErrFileNotExist:
                //..
          return
        default:
                //...
}}

3.2 通过errors.Is,errors.As

参考阅读: https://juejin.cn/post/7203341999956164664

var BaseErr = errors.New("base error")
​
func main() {
   err1 := fmt.Errorf("wrap base: %w", BaseErr)
   err2 := fmt.Errorf("wrap err1: %w", err1)
   println(err2 == BaseErr)
   if !errors.Is(err2, BaseErr) {
      panic("err2 is not BaseErr")
   }
   println("err2 is BaseErr")
}

//输出:
//false
//err2 is BaseErr
type TypicalErr struct {
   e string
}
func (t TypicalErr) Error() string {
   return t.e
}
func main() {
   err := TypicalErr{"typical error"}
   err1 := fmt.Errorf("wrap err: %w", err)
   err2 := fmt.Errorf("wrap err1: %w", err1)
   var e TypicalErr
   if !errors.As(err2, &e) {
      panic("TypicalErr is not on the chain of err2")
   }
   println("TypicalErr is on the chain of err2")
   println(err == e)
}
//输出:
//TypicalErr is on the chain of err2
//true

errors.join

package main

import (
    "errors"
    "fmt"
)

type CustomError struct {
    Code int
    Msg  string
}

func (e *CustomError) Error() string {
    return fmt.Sprintf("Error %d: %s", e.Code, e.Msg)
}

func main() {
    err1 := &CustomError{Code: 404, Msg: "Not Found"}
    err2 := errors.New("generic error")

    combinedErr := errors.Join(err1, err2)

    var ce *CustomError
    if errors.As(combinedErr, &ce) {
        fmt.Println("Extracted custom error:", ce.Code, ce.Msg)
    }
}

四、关于堆栈信息 "golang.org/x/xerrors"

package main

import (
    "errors"
    "fmt"

    "golang.org/x/xerrors"
)

func main() {
    testxerrors()
}

func testxerrors() {
    originalErr := errors.New("original error")
    err := xerrors.Errorf("Wrap了一个错误%w", originalErr)

    fmt.Println(errors.Unwrap(err))
    fmt.Println(errors.Is(err, originalErr))
    fmt.Printf("%+v", err) //xerrors.Errorf%w,%+v含有堆栈信息

}

func testOrgErrors() {
    e := errors.New("原始错误e")
    w := fmt.Errorf("Wrap了一个错误%w", e)
    fmt.Println(errors.Unwrap(w))
    fmt.Printf("%+v", w) //fmt.Errorf%w,然后%+v没有堆栈信息
}

1 对 “error知识汇总”的想法;

发表回复