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