go语言错误

  • error类型是个接口
  1. type error interface{
  2. Error() string
  3. }

if err!=nil

  • 函数调用时判断返回值

errors.New 创建error

  1. package main
  2. import (
  3. "errors"
  4. "fmt"
  5. "strings"
  6. )
  7. func validateArgs(name string) (ok bool, err error) {
  8. if strings.HasPrefix(name, "mysql") {
  9. return true, nil
  10. } else {
  11. return false, errors.New("name must startwith mysql")
  12. }
  13. }
  14. func main() {
  15. s1 := "mysql-abc"
  16. s2 := "redis-abc"
  17. _, err := validateArgs(s1)
  18. if err != nil {
  19. fmt.Println("[s1 validate 失败]", err)
  20. }
  21. _, err = validateArgs(s2)
  22. if err != nil {
  23. fmt.Println("[s2 validate 失败]", err)
  24. }
  25. }

复杂的错误类型

  • 以os包举例 提供了 LinkError、PathError、SyscallError
  • 上述error都是实现了error接口的错误类型
  • 可以用switch err.(type)判断类型
  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "os"
  6. )
  7. func main() {
  8. file, err := os.Stat("test.txt")
  9. if err != nil {
  10. switch err.(type) {
  11. case *os.PathError:
  12. log.Printf("PathError")
  13. case *os.LinkError:
  14. log.Printf("LinkError")
  15. case *os.SyscallError:
  16. log.Printf("SyscallError")
  17. default:
  18. log.Printf("unknown error")
  19. }
  20. } else {
  21. fmt.Println(file)
  22. }
  23. }

自定义error

  • errors.New 单独的error ,基础的error
  • 自定义结构体 ,再原始错误的基础上再封自己的错误信息
  • 如下
  1. package main
  2. import (
  3. "errors"
  4. "fmt"
  5. )
  6. type MyError struct {
  7. err error
  8. msg string // 自定义的error字符串
  9. }
  10. func (e *MyError) Error() string {
  11. return e.err.Error() + e.msg
  12. }
  13. func main() {
  14. err := errors.New("原始的错误")
  15. newErr := MyError{
  16. err: err,
  17. msg: "[是研发的锅]",
  18. }
  19. fmt.Println(newErr.Error())
  20. }
  • 弊端就是要定义很多 error结构体

golang 1.13中的Error Wrapping 错误嵌套

  • 目的是很上面的一样 ,扩展error信息
  • 使用 fmt.ErrorF(newErrorStr %w,e)
  • 好处就是不需要像上面一样定义结构体了,代码如下
  1. package main
  2. import (
  3. "errors"
  4. "fmt"
  5. )
  6. func main() {
  7. e := errors.New("原始错误01")
  8. w := fmt.Errorf("Wrap了一个新的错误 :%w", e)
  9. fmt.Println(w)
  10. }