遇到代码报错error,打印出error传递过程很重要

172 阅读2分钟

1.error格式化 和 error的重构

package main
import (
   "errors"
   "fmt"
)
func main() {
   err1 := fmt.Errorf("%s", "this is a err")
   fmt.Printf("%#v\n", err1)//this is a err

   err2 := errors.New("this is a err")
   fmt.Printf("%#v\n", err2)//this is a err

   if err1 == err2 {
      //错误提示字符串内容相等,但是两个错误不相等,是因为error底层返回的是指针
      fmt.Println("格式化后的error和重构的error相等")
   }
}

2.打印出error传递过程

myErr 包是出错位置的起点,怎样可以在其他包中打印出这一起点路径???

package myErr

import (
   "database/sql"
   "fmt"

   "github.com/astaxie/beego/orm"
   "github.com/pkg/errors"
)
// Text1 返回错误+提示字符串+路径【error报错的信息栈】
func Text1() error {
   return errors.Wrap(sql.ErrNoRows, "sql模块错误提示:")
}

// Text2 返回错误+字符串提示
func Text2() error {
   return errors.WithMessage(sql.ErrNoRows, "xxxxxxxx")
}

// Text3 返回错误
func Text3() error {
   return errors.Cause(sql.ErrNoRows)
}

// T1 返回错误+路径【error报错的信息栈】
func T1() error {
   return errors.New(orm.ErrNoRows.Error())
}
// T2 返回错误+ 提示字符串 +路径【error报错的信息栈】
func T2() error {
   return errors.New(errors.Wrap(sql.ErrNoRows, "sql模块错误提示:").Error())
}
package main

import (
   "fmt"

   "github.com/astaxie/beego/logs"
   "xiaohaizi/66/command/myErr"
)

func init() {
   logs.EnableFuncCallDepth(true)
   logs.SetLogFuncCallDepth(3)
   _ = logs.SetLogger("console")
}

func main() {

   fmt.Println("----------------------------------------------------Text1()")
   logs.Error("%+v", myErr.Text1())
   fmt.Println("----------------------------------------------------Text2()")
   logs.Error("%+v\n", myErr.Text2())
   fmt.Println("----------------------------------------------------Text3()")
   logs.Error("%+v\n", myErr.Text3())
   fmt.Println("-----------------------------------------------------------")
}

终端打印输出:【errors.Wrap是最友好的打印,程序出错可立马看出报错起点】

    ----------------------------------------------------Text1()
    2023/05/30 19:09:38.861 [E] [main.go:32]  sql: no rows in result set
    sql模块错误提示:
    xiaohaizi/66/command/myErr.Text1
    D:/share/command/error处理/myErr/myErr.go:19
    main.main
    D:/share/command/error处理/main.go:32
    runtime.main
    C:/go1.19.5/src/runtime/proc.go:250
    runtime.goexit
    C:/go1.19.5/src/runtime/asm_amd64.s:1594
    ----------------------------------------------------Text2()
    2023/05/30 19:09:38.880 [E] [main.go:34]  sql: no rows in result set
    xxxxxxxx

    ----------------------------------------------------Text3()
    2023/05/30 19:09:38.881 [E] [main.go:36]  sql: no rows in result set

    -----------------------------------------------------------

3.error重构的层数影响打印效果

func text2() {
   //下面两个打印的区别是:
   //【重构1次】的error也可打印出error栈信息
   logs.Info("%+v\n", myErr.T1())
   //把重构的error信息转成string打印
   logs.Info("%+v\n", myErr.T1().Error())
   //【重构2次】的error不可打印出error栈信息
   logs.Info("%+v\n", errors.New(myErr.T1().Error()))

   //使用Wrap
   //【重构1层】可以打印出完整路径
   logs.Info("-----------------------打印+string+重构 T1()")
   logs.Error("%+v\n", myErr.T2())
   //【重构2层】不可以打印出完整路径
   logs.Info("-----------------------打印+string+重构+string+重构 T1()")
   logs.Error("%+v\n", errors.New(myErr.T2().Error()))
}