error知识汇总
一. 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没有堆栈信息
}
original error
true
Wrap了一个错误original error:
main.testxerrors
D:/prjs/golang/study1/main.go:16
– original error