• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    基于golang如何实现error工具包详解

    前言

    对于一门编程语言的开发者,类库包管理是一项考核编程语言成熟度的重要指标之一,Golang 也不例外。笔者在日常使用Golang语言开发系统程序时发现,在 Golang 的世界里,存在着大量的技术实现讨论和各种自制的解决方案。

    最近在开发Go项目,发现Go语言本身存在的error并没有像触发panic时显示详细的调试信息。对于复杂的系统而言,这会让我们开发者需要一定的时间才能定位到错误。所以我们基本Go本身的error封装了一个可以快速定位错误工具包。下面让我们来看看这个工具包是怎么实现的。

    设计思想

    实现思路

    工具包中主要是对堆栈信息的处理,就是如何才能定位到error的产生位置,通过查看官方文档,我们发现通过runtime包中的Callers和CallersFrames函数可以获取当前函数调用的堆栈信息。并且通过Skip参数和自定义过滤条件即可拿到error的产生位置。具体的实现过程如下:

    对外提供的2个函数的实现

    type Error struct {
     err  error
     msg  string
     fullMsg string
     stackTrace
    }
    
    func Errf(err error, format string, args ...interface{}) *Error {
     e := Error{
      err: err,
      msg: fmt.Sprintf(format, args),
     }
     e.fullMsg = e.genFullMsg()
     return e
    }
    
    func Err(err error, args ...interface{}) *Error {
     e := Error{
      err: err,
      msg: fmt.Sprint(args),
     }
     e.fullMsg = e.genFullMsg()
     return e
    }

    堆栈信息的实现

    type stackTrace struct {
     // stack info
     data string
     callers []uintptr
    }
    
    func (err *Error) getStackTrace() string {
     if strings.TrimSpace(err.data) == "" {
      return err.genStackTrace(5)
     }
     return err.data
    }
    
    func (err *Error) StackTrace() string {
     return err.data
    }
    
    func (err *Error) genStackTrace(skip int) string {
     if config.isPrintStack == 1 {
      var buffer bytes.Buffer
      buffer.WriteString("StackTrace:\n")
      var st [64]uintptr
      n := runtime.Callers(skip, st[:])
      err.callers = st[:n]
      frames := runtime.CallersFrames(err.callers)
      for {
       frame, ok := frames.Next()
       if !ok {
        break
       }
       if !strings.Contains(frame.File, "runtime/") {
        buffer.WriteString(fmt.Sprintf("%s\n\t%s:%d\n", 
        frame.Func.Name(), frame.File, frame.Line))
       }
      }
      err.data = buffer.String()
      return err.data
     }
     return ""
    }

    错误信息显示配置的实现

    const (
     //print stack info
     PRINTSTACK = 1
    )
    
    // global error config object
    var config *errConfig = errConfig{}
    
    // error config
    type errConfig struct {
     isPrintStack uint32
    }
    
    //set error config info
    func SetConfig(conf byte) {
     if (conf  PRINTSTACK) != 0 {
      atomic.CompareAndSwapUint32(config.isPrintStack, 0, 1)
     }
    }

    测试

    func init() {
     errors.SetConfig(errors.PRINTSTACK)
    }
    
    func main() {
     a := func() {
      err := errors.Err(nil, "this is an inner error")
      fmt.Print(err.StackTrace())
      b := errors.Errf(err, "this is a %s message", "test").Error()
      fmt.Println(b)
     }
     a()
    }

    错误信息如下所示

     

    结尾

    该工具包只是对error信息和堆栈信息的封装,还存在含多不足的地方。如果各位有好的意见。欢迎指点。

    总结:

    以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

    您可能感兴趣的文章:
    • golang 打印error的堆栈信息操作
    • 修复 Mac brew 安装 mongodb 报 Error: No available formula with the name ‘mongodb’ 问题详解
    • Django错误:TypeError at / ''bool'' object is not callable解决
    • 解决启动MongoDB错误:error while loading shared libraries: libstdc++.so.6:cannot open shared object file:
    • django.db.utils.ProgrammingError: (1146, u“Table‘’ doesn’t exist”)问题的解决
    • GO语言标准错误处理机制error用法实例
    • 浅析golang开发Error的使用详解
    上一篇:Go 并发实现协程同步的多种解决方法
    下一篇:利用golang进行OpenCV学习和开发的步骤
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    基于golang如何实现error工具包详解 基于,golang,如何,实现,error,