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

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    golang 打印error的堆栈信息操作

    众所周知,目前的golang error只关注Error()信息,而不关注它的堆栈路径,对错误的定位大多数通过

    log.SetFlags(log.Llongfile| log.LstdFlags)
    log.Println(e)

    一旦代码分层,为了定位错误,可能出现每一个层次的同一个error,都得log好几次,比如:

    func DB()error{
    	return errors.New("time out")
    }
    func Dao()error{
        if er:= DB();er!=nil{
        	 log.Println(er)
        	 return error
        }
        return nil
    }
    func Service()error{
        if er:= Dao();er!=nil{
        	 log.Println(er)
        	 return error
        }
        return nil
    }
    func Control()error{
        if er:= Service();er!=nil{
        	 log.Println(er)
        	 return error
        }
        return nil
    }    
    

    如何一次性抛出错误,把该错误的堆栈全部都拿住呢

    以模拟一次请求-分发-服务-数据库操作为例:

    package main
    import (
    	"errors"
    	"fmt"
    	"github.com/fwhezfwhez/errorx"
    )
    func main() {
    	if e := Control(); e != nil {
    		e.(errorx.Error).PrintStackTrace()
    		// log.Println(e.(errorx.Error).StackTrace())
    	} else {
    		Reply()
    	}
    }
    // assume an engine to connect mysql
    func DB() error {
    	return errors.New("connect to mysql time out")
    }
    // handle database operation
    func Dao() error {
    	if er := DB(); er != nil {
    		return errorx.New(er)
    	}
    	return nil
    }
    // handle logic service
    func Service() error {
    	if er := Dao(); er != nil {
    		return errorx.Wrap(er)
    	}
    	return nil
    }
    // handle request distribute from main
    func Control() error {
    	if er := Service(); er != nil {
    		return errorx.ReGen(er, errors.New("inner service error,please call admin for help"))
    	}
    	return nil
    }
    // reply a the request
    func Reply(){
    	fmt.Println("handle success")
    }
    

    执行结果:

    StackTrace | CausedBy

    G:/go_workspace/GOPATH/src/errorX/example/main.go: 26 | connect to mysql time out

    G:/go_workspace/GOPATH/src/errorX/example/main.go: 34 | connect to mysql time out

    G:/go_workspace/GOPATH/src/errorX/example/main.go: 42 | inner service error,please call admin for help

    补充:golang 异常退出堆栈捕获

    利用golang自带包 runtime/debug 异常时打印

    DebugInfo.go

    package main
    import (
        "fmt"
        "os"
        "runtime/debug"
        "time"
    )
    func TryE() {
        errs := recover()
        if errs == nil {
            return
        }
        exeName := os.Args[0] //获取程序名称
        now := time.Now()  //获取当前时间
        pid := os.Getpid() //获取进程ID
        time_str := now.Format("20060102150405")                          //设定时间格式
        fname := fmt.Sprintf("%s-%d-%s-dump.log", exeName, pid, time_str) //保存错误信息文件名:程序名-进程ID-当前时间(年月日时分秒)
        fmt.Println("dump to file ", fname)
        f, err := os.Create(fname)
        if err != nil {
            return
        }
        defer f.Close()
        f.WriteString(fmt.Sprintf("%v\r\n", errs)) //输出panic信息
        f.WriteString("========\r\n")
        f.WriteString(string(debug.Stack())) //输出堆栈信息
    }
    

    测试异常捕获 main.go

    package main
    import (
        "fmt"
        "time"
    )
    func main() {
        defer TryE()
        fmt.Println(time.Now())
        panic(-2)
        fmt.Println("panic restore now, continue.")
    }
    

    查看堆栈可以定位main 里第11行抛出异常-2.

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。

    您可能感兴趣的文章:
    • GO语言标准错误处理机制error用法实例
    • Go 自定义error错误的处理方法
    • 浅谈Go语言的error类型
    • 浅析golang开发Error的使用详解
    • Go应用中优雅处理Error的技巧总结
    上一篇:golang中json和struct的使用说明
    下一篇:对Golang中的FORM相关字段理解
  • 相关文章
  • 

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

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

    golang 打印error的堆栈信息操作 golang,打印,error,的,堆栈,