github.com/code-reading/golang@v0.0.0-20220303082512-ba5bc0e589a3/coding/errors/as.go (about) 1 package main 2 3 import ( 4 "errors" 5 "fmt" 6 "io/fs" 7 "os" 8 ) 9 10 // errors.As 可以非常方便抽取结构化中错误值部分 11 12 /* 13 比如,有一个业务错误信息, path: xxxx, Os: drawin, error:path not exist 14 这个错误信息很难进行字段提取 15 可以通过自定义错误方法, 提出这个错误信息 16 17 // 自定义错误类型 18 19 type PathError struct { 20 path string 21 Os string 22 err error 23 } 24 // 实现错误接口 25 func (e PathError)Error()string { 26 return fmt.Sprintf("xxx, xx ,x ", e.path, e.os, e.err) 27 } 28 29 业务函数 30 func A() error { 31 return PathError{path:xxx, os:xxx, err:errors.New("xxxx")} 32 } 33 if e = A() ; e !=nil { 34 var pe *PathError 35 注意: 这里明确知道返回的e 的类型就是 PathError, 且pe 传递为地址传递 ,否则会panic 36 当然 如果要进一步提取PathError, 比如脱敏等, 可以在PathError 在实现一个As(error, interface{})方法 37 if errors.As(e, &pe) { 38 // dosomething with pe 39 fmt.Println("path:", pe.path) 40 } 41 } 42 */ 43 44 func main() { 45 if _, err := os.Open("non-existing"); err != nil { 46 // os.Open 返回的错误类型 是 *fs.PathError 47 var pathError *fs.PathError 48 if errors.As(err, &pathError) { 49 fmt.Println("Failed at path:", pathError.Path) 50 } else { 51 fmt.Println(err) 52 } 53 } 54 55 // Output: 56 // Failed at path: non-existing 57 }