使用github.com/pkg/errors包快速定位错误

package main

import (
   "bufio"
   "fmt"
   "github.com/pkg/errors"
   "os"
   "path/filepath"
   "time"
)

func func1(num int64) (result int64, err error) {
   defer func() {
      rec := recover()
      if rec != nil {
         err, _ = rec.(error)
         err = errors.WithStack(err) // 附加调用堆栈信息
      }
   }()

   // 当num的值为0时会报panic,然后被defer-recover捕获错误
   result = 1024 / num

   return
}

func func2(num int64) (result int64, err error) {
   result, err = func1(num)

   // 由于发生了错误,附加调用堆栈信息然后返回即可
   if err != nil {
      err = errors.WithStack(err) // 附加调用堆栈信息
      return
   }

   return
}

func WriteErrorLog(err error) {
   curPath, _ := filepath.Abs(".")   // 当前目录硬盘路径,结尾不带“/”
   logPath := curPath + "/log"       // 错误日志文件保存目录
   logFile := logPath + "/error.log" // 错误日志文件硬盘路径

   // 创建日志文件保存目录(若目录存在则忽略)
   _ = os.MkdirAll(logPath, 0755)

   // 打开日志文件(不存在则创建|只写模式|尾部追加)
   file, _ := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)

   // 关闭日志文件
   defer func(file *os.File) {
      _ = file.Close()
   }(file)

   // 获取当前时间
   location, _ := time.LoadLocation("Asia/Shanghai")
   now := time.Now().In(location).Format("2006/01/02 15:04:05.999999")

   // 写入文件
   writer := bufio.NewWriter(file)
   _, _ = writer.WriteString(fmt.Sprintf("[error] %+v %+v\n\n", now, err))
   _ = writer.Flush()
}

func main() {
   result, err := func2(0)
   if err != nil {
      // 这里会打印一大段调用堆栈信息(具体可看最后)
      info := fmt.Sprintf("%+v", err)
      fmt.Println(info)

      // 将错误信息写入日志文件(也可以写入数据库)
      WriteErrorLog(err)
   } else {
      fmt.Printf("result = %+v \n", result)
   }
}

// ========== 调用堆栈信息·开始 ========== //

// runtime error: integer divide by zero
// main.func1.func1
//        D:/go/demo/cmd/main.go:17
// runtime.gopanic
//        C:/Program Files (x86)/go/src/runtime/panic.go:890
// runtime.panicdivide
//        C:/Program Files (x86)/go/src/runtime/panic.go:239
// main.func1
//        D:/go/demo/cmd/main.go:22
// main.func2
//        D:/go/demo/cmd/main.go:28
// main.main
//        D:/go/demo/cmd/main.go:66
// runtime.main
//        C:/Program Files (x86)/go/src/runtime/proc.go:250
// runtime.goexit
//        C:/Program Files (x86)/go/src/runtime/asm_amd64.s:1598
// main.func2
//        D:/go/demo/cmd/main.go:32
// main.main
//        D:/go/demo/cmd/main.go:66
// runtime.main
//        C:/Program Files (x86)/go/src/runtime/proc.go:250
// runtime.goexit
//        C:/Program Files (x86)/go/src/runtime/asm_amd64.s:1598

// ========== 调用堆栈信息·结束 ========== //

// ========== 总结 ========== //
// 1、使用github.com/pkg/errors包可以获取错误的调用堆栈信息,利用这些信息可以很快定位错误方便debug。

Copyright © 2024 码农人生. All Rights Reserved