亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Go項(xiàng)目分層下的最佳error處理方式分享

 更新時(shí)間:2023年06月21日 08:26:34   作者:陳明勇  
這篇文章主要來和大家一起探討?Go?項(xiàng)目分層下的最佳?error?處理方式,準(zhǔn)備好了嗎?準(zhǔn)備一杯你最喜歡的飲料或茶,隨著本文一探究竟吧

前言

Go 語言中,對(duì)于程序中可能出現(xiàn)的問題,比如數(shù)據(jù)庫連接失敗,文件讀取錯(cuò)誤等,都是使用基于內(nèi)置的 error 接口類型的值來表示和處理錯(cuò)誤。而在分層的項(xiàng)目中,如何最佳處理 error成為眾多人關(guān)注的問題,本文將探討 Go 項(xiàng)目分層下的最佳 error 處理方式。準(zhǔn)備好了嗎?準(zhǔn)備一杯你最喜歡的飲料或茶,隨著本文一探究竟吧。

常見分層下的 error 處理

以典型的 MVC ( daoservicecontroller/middleware) 分層結(jié)構(gòu)舉例,常見的錯(cuò)誤處理大致如下:

// controller / middleware
res, err := service.GetById(ctx, id)
if err != nil {
    log.Errorf(ctx, "service.GetById failed, id=%s, error=%v", err)
    ······
}
······
// service  
article, err := dao.GetById(ctx, id)
if err != nil {
    log.Errorf(ctx, fmt.Errorf("dao.GetById failed, error=%v", err))
    return fmt.Errorf("dao.GetById failed, error=%v", err)
}
······
// dao
······
if err != nil {
    log.Errorf(ctx, fmt.Errorf("GetById failed, id=%s, error=%v", id, err))
    return fmt.Errorf("GetById failed, id=%s, error=%v", id, err)
}
······

以上錯(cuò)誤處理的方式,在每一層都打印一條錯(cuò)誤日志,然后對(duì)得到的 error 進(jìn)行二次封裝。雖然以上處理方式可以使我們?cè)诓榭慈罩緯r(shí)方便故障排查和問題定位,同時(shí)提供了錯(cuò)誤的上下文信息,但也存在以下問題:

  • 每層都打印日志,帶來了大量日志;
  • 字符串拼接費(fèi)時(shí)費(fèi)力,缺乏統(tǒng)一規(guī)范,可能導(dǎo)致理解困難;
  • 通過字符串拼接,獲得新 error,破壞了原始 error,會(huì)導(dǎo)致等值判定失敗,難以獲取詳細(xì)的堆棧關(guān)聯(lián)。

分層下的最佳 error 處理方式

遵循以下建議,我們可以更好地處理 error

  • 1、一個(gè) error,應(yīng)該只被處理一次
  • 2、讓 error 包含更多的信息
  • 3、原始 error,應(yīng)保證完整性,不被破壞
  • 4、error 需要被日志記錄

什么意思呢?為了確保 error 處理的有效性,對(duì)于某一層來說,應(yīng)該保證每個(gè)錯(cuò)誤只被處理一次,要么打印 error 信息,要么將其傳遞給上一層,而不是每一層都獨(dú)立打印 error 信息。

同時(shí),在傳遞錯(cuò)誤給上一層時(shí),應(yīng)該附帶有用的額外信息,并確保不破壞原始錯(cuò)誤的完整性,以保證錯(cuò)誤的可追溯性。最后,通過記錄錯(cuò)誤日志可以幫助我們進(jìn)行問題排查。

如圖所示:

Dao 層遇到原始錯(cuò)誤 Original Error 后,我們可以將其與需要的額外信息封裝,組成一個(gè)新的 error ,然后傳遞給上一層,逐層附加信息,直至傳遞到 controller 層,最終得到一個(gè)全新的 error,其中包含 Original error 和每一層添加的額外信息。

通過最終得到的這個(gè) error,我們可以像剝洋蔥一樣逐層解開,追溯到 Original error ,并獲取我們所需的信息。如果 controller 是最頂層,我們可以打印完整的錯(cuò)誤信息,然后獲取 Original Error,并打印其所包含的 堆棧信息

Wrap error

盡管前面已經(jīng)探討了分層下的最佳 error 處理方式,但我們會(huì)發(fā)現(xiàn)官方標(biāo)準(zhǔn)庫errors 所提供的函數(shù)并不能滿足我們的需求,我們不能借助現(xiàn)有函數(shù)對(duì)原始錯(cuò)誤附加額外信息且不破壞其完整性。在這種情況下,我們可以借助第三方庫 github.com/pkg/errors 來完成我們的需求。

github.com/pkg/errors 提供了很多實(shí)用的函數(shù),例如:

  • Wrap(err error, message string) error:該函數(shù)基于原始錯(cuò)誤 err,返回一個(gè)帶有堆棧跟蹤信息和附加信息 message 的新 error
  • Wrapf(err error, format string, args ...interface{}) error: 和上面的函數(shù)功能是一樣的,只不過可以對(duì)附加信息進(jìn)行格式化封裝
  • WithMessage(err error, message string) error:該函數(shù)基于原始錯(cuò)誤 err,返回一個(gè)附加信息 message 的新 error
  • WithMessagef(err error, format string, args ...interface{}) error: 和上面的函數(shù)功能是一樣的,只不過可以對(duì)附加信息進(jìn)行格式化封裝
  • Cause(err error) error:該函數(shù)用于提取 err 中的原始 error,它會(huì)遞歸地檢查 error,直到找到最底層的原始 error,如果存在的話

了解了以上函數(shù)的功能,我們來看看項(xiàng)目分層下最佳 error 的具體實(shí)現(xiàn)。

// controller / middleware  
res, err := service.GetById(ctx, id)  
if err != nil {  
  log.Errorf(ctx, "service.GetById failed, original error: %T %v", errors.Cause(err), errors.Cause(err))  
  log.Errorf(ctx, "stack trace: \n%+v\n", err)  
······  
}  
······  
// service  
article, err := dao.GetById(ctx, id)  
if err != nil {  
  return errors.WithMessage(err, "dao.GetById failed")  
}  
······  
// dao  
······  
if err != nil {  
  return errors.Wrapf(err, "GetById failed, id=%s, error=%v", id, err)  
}  
······

當(dāng)在 Dao 層遇到原始錯(cuò)誤 Original Error 后,使用 errors.Wrap() 對(duì)錯(cuò)誤進(jìn)行封裝。這個(gè)封裝操作可以在保留根因(Origin error)的同時(shí),提供堆棧信息,并添加額外的上下文信息,然后將封裝后的錯(cuò)誤傳遞給上一層處理。

當(dāng) service 層接收到 error 之后,使用 errors.WithMessage() 函數(shù),將額外的信息附加到錯(cuò)誤上,并繼續(xù)將錯(cuò)誤向上層傳遞,直至到達(dá) controller 層。在 controller 層,我們可以打印出根因的類型、信息以及堆棧信息,以便更好地進(jìn)行問題排查。

小結(jié)

本文對(duì) Go 項(xiàng)目分層下的最佳 error 處理方式進(jìn)行介紹,并通過使用 github.com/pkg/errors 庫中的一些實(shí)用函數(shù)來提供實(shí)現(xiàn)示例。

盡管本文基于 MVC 分層結(jié)構(gòu)進(jìn)行介紹,但實(shí)際上大多數(shù)項(xiàng)目的分層結(jié)構(gòu)可能各不相同,因此在確定錯(cuò)誤處理方式和策略時(shí)需要考慮具體情況。然而,我相信通過參考本文提出的四點(diǎn)建議和實(shí)現(xiàn)示例或其他更好的建議,一定能夠確定最佳的錯(cuò)誤處理方式。

到此這篇關(guān)于Go項(xiàng)目分層下的最佳error處理方式分享的文章就介紹到這了,更多相關(guān)Go error處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang通脈之?dāng)?shù)據(jù)類型詳情

    Golang通脈之?dāng)?shù)據(jù)類型詳情

    這篇文章主要介紹了Golang通脈之?dāng)?shù)據(jù)類型,在編程語言中標(biāo)識(shí)符就是定義的具有某種意義的詞,比如變量名、常量名、函數(shù)名等等,Go語言中標(biāo)識(shí)符允許由字母數(shù)字和_(下劃線)組成,并且只能以字母和_開頭,更詳細(xì)內(nèi)容請(qǐng)看下面文章吧
    2021-10-10
  • GO語言類型查詢類型斷言示例解析

    GO語言類型查詢類型斷言示例解析

    這篇文章主要為大家介紹了GO語言類型判斷及類型斷言,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • 使用Lumberjack+zap進(jìn)行日志切割歸檔操作

    使用Lumberjack+zap進(jìn)行日志切割歸檔操作

    這篇文章主要介紹了使用Lumberjack+zap進(jìn)行日志切割歸檔操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Golang數(shù)據(jù)類型比較詳解

    Golang數(shù)據(jù)類型比較詳解

    這篇文章主要圍繞Golang數(shù)據(jù)類型比較詳細(xì)展開,文中有詳細(xì)的比較過程,需要的朋友可以參考一下
    2023-04-04
  • Go源碼字符串規(guī)范檢查lint工具strchecker使用詳解

    Go源碼字符串規(guī)范檢查lint工具strchecker使用詳解

    這篇文章主要為大家介紹了Go源碼字符串規(guī)范檢查lint工具strchecker使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • Golang中漏洞數(shù)據(jù)庫的使用詳解

    Golang中漏洞數(shù)據(jù)庫的使用詳解

    govulncheck是Golang中的漏洞掃描工具,它強(qiáng)大功能的背后,離不開?Go?漏洞數(shù)據(jù)庫(Go?vulnerability?database)的支持,所以本文就來為大家詳細(xì)講解下?Go?漏洞數(shù)據(jù)庫相關(guān)的知識(shí)
    2023-09-09
  • 詳解Go語言如何判斷兩個(gè)對(duì)象是否相等

    詳解Go語言如何判斷兩個(gè)對(duì)象是否相等

    在編程中,判斷兩個(gè)對(duì)象是否相等是一項(xiàng)常見的任務(wù),同時(shí)判斷對(duì)象是否相等在很多情況下都非常重要,所以在接下來的內(nèi)容中,我們將詳細(xì)介紹在?Go?語言中如何判斷對(duì)象是否相等的方法和技巧,需要的可以參考一下
    2023-06-06
  • go語言中的指針自動(dòng)解引用

    go語言中的指針自動(dòng)解引用

    Go語言中,編譯器會(huì)自動(dòng)解引用指針來訪問字段,自動(dòng)解引用使得使用指針訪問結(jié)構(gòu)體字段和方法變得更加直觀,降低了編程錯(cuò)誤的風(fēng)險(xiǎn),并使代碼更易于理解和維護(hù)
    2024-10-10
  • golang開發(fā)微框架Gin的安裝測(cè)試及簡(jiǎn)介

    golang開發(fā)微框架Gin的安裝測(cè)試及簡(jiǎn)介

    這篇文章主要為大家介紹了golang微框架Gin的安裝測(cè)試及簡(jiǎn)介,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2021-11-11
  • golang中beego入門

    golang中beego入門

    Beego是一個(gè)基于Go語言的開源框架,用于構(gòu)建Web應(yīng)用程序和API,本文主要介紹了golang中beego入門,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12

最新評(píng)論