Go errors默认加堆栈信息的作用分析

 更新时间:2023年12月08日 08:56:03   作者:煎鱼  
这篇文章主要为大家介绍了Go errors默认加堆栈信息作用分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

背景

在 Go 语言中,错误处理是我们必须涉及和争议比较大的一个功能特性。今天我们不太探讨 if err != nil 的繁杂忧愁。

聚焦在 errors 标准库在排查、定位问题的诉求上。看看大家平时都是怎么做的。

平时我们在返回和处理错误时,一般使用 errors 标准库。其支持以下几个 API:

func As(err error, target any) bool
func Is(err, target error) bool
func Join(errs ...error) error
func New(text string) error
func Unwrap(err error) error

最简单的 Demo 如下:

func main() {
    err := errors.New("煎鱼出现错误了!")
    if err != nil {
        fmt.Println(err)
    }
}

输出结果:

煎鱼出现错误了!

看着非常基础,也没什么特别的。但如果是在生产等正式环境下出问题时,可能就没法这么愉快了。

但比较头疼的是:其错误信息缺乏了调用堆栈,在复杂程序下,你很难直观的知道是具体哪些关联的代码导致出现了这个报错。只能靠在代码中搜错误的文本,去猜测应该是这里的问题。

第三方库解决

因此很多同学会使用第三方的开源库 go-errors/errors。以下是他的简单代码演示:

import (
    "fmt"
    "github.com/go-errors/errors"
)
var Crashed = errors.Errorf("煎鱼变炸鱼了!")
func Crash() error {
    return errors.New(Crashed)
}
func main() {
    err := Crash()
    if err != nil {
        fmt.Println(err.(*errors.Error).ErrorStack())
        return
    }
}

输出结果:

$ go run main.go
*errors.Error 煎鱼变炸鱼了!
/Users/eddycjy/app/go/demo1/main.go:12 (0x1090645)
    main: return errors.New(Crashed)
/Users/eddycjy/app/go/demo1/main.go:12 (0x1090636)
    Crash: return errors.New(Crashed)
/usr/local/Cellar/go/1.21.1/libexec/src/runtime/internal/atomic/types.go:194 (0x103305b)
    (*Uint32).Load: return Load(&u.value)
/usr/local/Cellar/go/1.21.1/libexec/src/runtime/asm_amd64.s:1650 (0x105d501)
    goexit: BYTE    $0x90    // NOP

该库会默认记录 ErrorStack 并且可以通过相应的方法。

新提案

前面提到的问题和解决方案,一直有人在提和重复造新的轮子。最近 Go 核心团队 @Ian Lance Taylor 提出了新的提案《proposal: errors: let GODEBUG=errstacktrace request stack backtraces》希望以此解决这个问题。

在提案中计划:增加一个新的 Go 运行时选项:GODEBUG=errstacktrace

在环境中设置该 GODEBUG 项后,errors.New 和 fmt.Errorf 函数将发生变化,将堆栈跟踪纳入信息中。

新补充的堆栈跟踪将成为 Error 方法返回的字符串的一部分,将会是一个多行的字符串内容。

总结

Go 的 errors 总是纷纷扰扰,本次的提案也是拉扯了多年的结果。本次是想往 GODEBUG 上做开关选项,但也有许多同学想在编译时就能指定,不用每次配一堆 GODEBUG。(虽然实际效果差不多)

整体来讲,这个需求如果能够落地,还是不错的。能够解决一些缺失调用堆栈,不太能明确错误抛出在哪的小麻烦。也能解决一些第三方库存在原因,不用再额外维护了。

以上就是Go errors默认加堆栈信息的作用分析的详细内容,更多关于Go errors堆栈信息的资料请关注脚本之家其它相关文章!

相关文章

  • Go语言展现快速排序算法全过程的思路及代码示例

    Go语言展现快速排序算法全过程的思路及代码示例

    这篇文章主要介绍了Go语言展现快速排序算法全过程的思路及代码示例,文章最后作者还提到了对Quick Sort算法优化的一些想法,需要的朋友可以参考下
    2016-04-04
  • Golang Mutex错过会后悔的重要知识点分享

    Golang Mutex错过会后悔的重要知识点分享

    互斥锁 Mutex 是并发控制的一个基本手段,是为了避免并发竞争建立的并发控制机制,本文主要为大家整理了一些Mutex的相关知识点,希望对大家有所帮助
    2023-07-07
  • Go语言中goroutine和WaitGroup的使用示例详解

    Go语言中goroutine和WaitGroup的使用示例详解

    goroutine 是Go中一个轻量级的线程, 只需要一个go关键字就可以创建一个goroutine,这篇文章主要介绍了Go语言中goroutine和WaitGroup的使用,需要的朋友可以参考下
    2023-03-03
  • Go语言基础函数包的使用学习

    Go语言基础函数包的使用学习

    本文通过一个实现加减乘除运算的小程序来介绍go函数的使用,以及使用函数的注意事项,并引出了对包的了解和使用,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • 用Go语言标准库实现Web服务之项目介绍

    用Go语言标准库实现Web服务之项目介绍

    从本节开始将从后端到前端一步一步实现一个Go语言Web服务,后端除了MySQL驱动,全部使用Go语言标准库来实现一个小型项目,本篇将简单的介绍一下项目开发要准备的流程,感兴趣的同学可以阅读一下
    2023-05-05
  • GOLang判断进程是否存在实现方式

    GOLang判断进程是否存在实现方式

    该文主要介绍了使用Go语言编写进程检测工具的方法,由于Go语言本身没有直接获取进程信息的功能,作者决定通过执行命令的方式实现,最终给出了优化后的代码示例
    2026-04-04
  • go xorm框架的使用

    go xorm框架的使用

    xorm框架和Spring Data Jpa有点相似,可以对比学习,对于这个框架感觉还不错,闲暇时间学习一下
    2021-05-05
  • Go语言使用Timeout Context取消任务的实现

    Go语言使用Timeout Context取消任务的实现

    本文主要介绍了Go语言使用Timeout Context取消任务的实现,包括基本的任务取消和控制HTTP客户端请求的超时,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01
  • 关于golang中死锁的思考与学习

    关于golang中死锁的思考与学习

    本文主要介绍了关于golang中死锁的思考与学习,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • Golang中map的三种声明定义方式实现

    Golang中map的三种声明定义方式实现

    本文主要介绍了Golang中map的三种声明定义方式实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02

最新评论