Go errors默認(rèn)加堆棧信息的作用分析
背景
在 Go 語(yǔ)言中,錯(cuò)誤處理是我們必須涉及和爭(zhēng)議比較大的一個(gè)功能特性。今天我們不太探討 if err != nil 的繁雜憂愁。
聚焦在 errors 標(biāo)準(zhǔn)庫(kù)在排查、定位問題的訴求上??纯创蠹移綍r(shí)都是怎么做的。
平時(shí)我們?cè)诜祷睾吞幚礤e(cuò)誤時(shí),一般使用 errors 標(biāo)準(zhǔn)庫(kù)。其支持以下幾個(gè) 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
最簡(jiǎn)單的 Demo 如下:
func main() { err := errors.New("煎魚出現(xiàn)錯(cuò)誤了!") if err != nil { fmt.Println(err) } }
輸出結(jié)果:
煎魚出現(xiàn)錯(cuò)誤了!
看著非?;A(chǔ),也沒什么特別的。但如果是在生產(chǎn)等正式環(huán)境下出問題時(shí),可能就沒法這么愉快了。
但比較頭疼的是:其錯(cuò)誤信息缺乏了調(diào)用堆棧,在復(fù)雜程序下,你很難直觀的知道是具體哪些關(guān)聯(lián)的代碼導(dǎo)致出現(xiàn)了這個(gè)報(bào)錯(cuò)。只能靠在代碼中搜錯(cuò)誤的文本,去猜測(cè)應(yīng)該是這里的問題。
第三方庫(kù)解決
因此很多同學(xué)會(huì)使用第三方的開源庫(kù) go-errors/errors
。以下是他的簡(jiǎn)單代碼演示:
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 } }
輸出結(jié)果:
$ 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
該庫(kù)會(huì)默認(rèn)記錄 ErrorStack 并且可以通過相應(yīng)的方法。
新提案
前面提到的問題和解決方案,一直有人在提和重復(fù)造新的輪子。最近 Go 核心團(tuán)隊(duì) @Ian Lance Taylor 提出了新的提案《proposal: errors: let GODEBUG=errstacktrace request stack backtraces》希望以此解決這個(gè)問題。
在提案中計(jì)劃:增加一個(gè)新的 Go 運(yùn)行時(shí)選項(xiàng):GODEBUG=errstacktrace
。
在環(huán)境中設(shè)置該 GODEBUG 項(xiàng)后,errors.New
和 fmt.Errorf
函數(shù)將發(fā)生變化,將堆棧跟蹤納入信息中。
新補(bǔ)充的堆棧跟蹤將成為 Error 方法返回的字符串的一部分,將會(huì)是一個(gè)多行的字符串內(nèi)容。
總結(jié)
Go 的 errors 總是紛紛擾擾,本次的提案也是拉扯了多年的結(jié)果。本次是想往 GODEBUG 上做開關(guān)選項(xiàng),但也有許多同學(xué)想在編譯時(shí)就能指定,不用每次配一堆 GODEBUG。(雖然實(shí)際效果差不多)
整體來講,這個(gè)需求如果能夠落地,還是不錯(cuò)的。能夠解決一些缺失調(diào)用堆棧,不太能明確錯(cuò)誤拋出在哪的小麻煩。也能解決一些第三方庫(kù)存在原因,不用再額外維護(hù)了。
以上就是Go errors默認(rèn)加堆棧信息的作用分析的詳細(xì)內(nèi)容,更多關(guān)于Go errors堆棧信息的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Golang實(shí)現(xiàn)短網(wǎng)址/短鏈服務(wù)的開發(fā)筆記分享
這篇文章主要為大家詳細(xì)介紹了如何使用Golang實(shí)現(xiàn)短網(wǎng)址/短鏈服務(wù),文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解一下2023-05-05golang實(shí)現(xiàn)對(duì)JavaScript代碼混淆
在Go語(yǔ)言中,你可以使用一些工具來混淆JavaScript代碼,一個(gè)常用的工具是Terser,它可以用于壓縮和混淆JavaScript代碼,你可以通過Go語(yǔ)言的`os/exec`包來調(diào)用Terser工具,本文給通過一個(gè)簡(jiǎn)單的示例給大家介紹一下,感興趣的朋友可以參考下2024-01-01Golang實(shí)現(xiàn)Redis網(wǎng)絡(luò)協(xié)議實(shí)例探究
這篇文章主要為大家介紹了Golang實(shí)現(xiàn)Redis網(wǎng)絡(luò)協(xié)議實(shí)例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01一個(gè)簡(jiǎn)單的Golang實(shí)現(xiàn)的HTTP Proxy方法
今天小編就為大家分享一篇一個(gè)簡(jiǎn)單的Golang實(shí)現(xiàn)的HTTP Proxy方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-08-08golang的time包:秒、毫秒、納秒時(shí)間戳輸出方式
這篇文章主要介紹了golang的time包:秒、毫秒、納秒時(shí)間戳輸出方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-12-12Go語(yǔ)言string,int,int64 ,float之間類型轉(zhuǎn)換方法
Go語(yǔ)言中int類型和string類型都是屬于基本數(shù)據(jù)類型,兩種類型的轉(zhuǎn)化都非常簡(jiǎn)單。下面通過本文給大家分享Go語(yǔ)言string,int,int64 ,float之間類型轉(zhuǎn)換方法,感興趣的朋友一起看看吧2017-07-07Go語(yǔ)言處理超大字符串型整數(shù)加減經(jīng)典面試詳解
這篇文章主要為大家介紹了Go語(yǔ)言處理超大字符串型整數(shù)加減經(jīng)典面試示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10