博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于golang实现的error工具包
阅读量:6079 次
发布时间:2019-06-20

本文共 2593 字,大约阅读时间需要 8 分钟。

写在前面的话

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

设计思想

  1. 工具包提供ErrErrf两个完善来登记错误,其用法分别类似于fmt.Printfmt.Printf的使用方式,在参数的定义中添加了innerError参数来实现错误的传递,其值可为nil.
  2. 对外提供StackTrace函数,方便使用者获取错误产生的堆栈信息。
  3. 通过SetConfig方式实现对错误信息显示的配置,如在生产环境不需要打印堆栈信息。通过响应的配置即可关闭。

实现思路

工具包中主要是对堆栈信息的处理,就是如何才能定位到error的产生位置,通过查看官方文档,我们发现通过runtime包中的CallersCallersFrames函数可以获取当前函数调用的堆栈信息。并且通过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 objectvar config *errConfig = &errConfig{}// error configtype errConfig struct {    isPrintStack uint32}//set error config infofunc 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信息和堆栈信息的封装,还存在含多不足的地方。如果各位有好的意见。欢迎指点。

转载地址:http://oghgx.baihongyu.com/

你可能感兴趣的文章
Win7无法添加用户的问题
查看>>
DCI:DCI学习总结
查看>>
- Shell - sort处理大文件(页 1) - ChinaUnix.net
查看>>
项目管理--执行过程组
查看>>
数据访问与sql语句的管理(一)
查看>>
前端开发框架
查看>>
风 记忆
查看>>
ARM中的PC和AXD的PC
查看>>
[转]关于ios 推送功能的终极解决
查看>>
C#中使用反射获取结构体实例
查看>>
GCT之语文细节知识
查看>>
【网站国际化必备】Asp.Net MVC 集成Paypal(贝宝)快速结账 支付接口 ,附源码demo...
查看>>
VC中使用GetModuleFileName获取应用程序路径
查看>>
Ecshop 最小起订量如何设置
查看>>
简单JavaScript语句实现搜索关键字高亮功能
查看>>
CentOS 6上安装xfce桌面环境
查看>>
SharedPreferences的工具类
查看>>
屏幕适配那点事
查看>>
nyoj-----幸运三角形
查看>>
C166 Interfacing C to Assembler
查看>>