精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

關于Go程序錯誤處理的一些建議

開發 后端
Go的錯誤處理這塊是日常被大家吐槽較多的地方,我在工作中也觀察到一些現象,比較嚴重的是在各層級的邏輯代碼中對錯誤的處理有些重復。

[[425992]]

本文轉載自微信公眾號「網管叨bi叨」,作者網管 。轉載本文請聯系網管叨bi叨公眾號。

Go的錯誤處理這塊是日常被大家吐槽較多的地方,我在工作中也觀察到一些現象,比較嚴重的是在各層級的邏輯代碼中對錯誤的處理有些重復。

比如,有人寫代碼就會在每一層都判斷錯誤并記錄日志,從代碼層面看,貌似很嚴謹,但是如果看日志會發現一堆重復的信息,等到排查問題時反而會造成干擾。

今天給大家總結三點Go代碼錯誤處理相關的最佳實踐給大家。

這些最佳實踐也是網上一些前輩分享的,我自己實踐后在這里用自己的語言描述出來,希望能對大家有所幫助。

認識error

Go程序通過error類型的值表示錯誤

error類型是一個內建接口類型,該接口只規定了一個返回字符串值的Error方法。

  1. type error interface { 
  2.     Error() string 

Go語言的函數經常會返回一個error值,調用者通過測試error值是否是nil來進行錯誤處理。

  1. i, err := strconv.Atoi("42"
  2. if err != nil { 
  3.     fmt.Printf("couldn't convert number: %v\n", err) 
  4.     return 
  5. fmt.Println("Converted integer:", i) 

error為nil時表示成功;非nil的error表示失敗。

自定義錯誤記得要實現error接口

我們經常會定義符合自己需要的錯誤類型,但是記住要讓這些類型實現error接口,這樣就不用在調用方的程序里引入額外的類型。

比如下面我們自己定義了myError這個類型,如果不實現error接口的話,調用者的代碼中就會被myError這個類型侵入。比如下面的run函數,在定義返回值類型時,直接定義成error即可。

  1. package myerror 
  2.  
  3. import ( 
  4.  "fmt" 
  5.  "time" 
  6.  
  7. type myError struct { 
  8.  Code int 
  9.  When time.Time 
  10.  What string 
  11.  
  12. func (e *myError) Error() string { 
  13.  return fmt.Sprintf("at %v, %s, code %d"
  14.   e.When, e.What, e.Code) 
  15.  
  16. func run() error { 
  17.  return &MyError{ 
  18.     1002, 
  19.     time.Now(), 
  20.     "it didn't work"
  21.  } 
  22.  
  23. func TryIt() { 
  24.  if err := run(); err != nil { 
  25.   fmt.Println(err) 
  26.  } 

如果myError不實現error接口的話,這里的返回值類型就要定義成myError類型。可想而知,緊接著調用者的程序里就要通過myError.Code == xxx 來判斷到底是哪種具體的錯誤(當然想要這么干得先把myError改成導出的MyError)。

那調用者判斷自定義error是具體哪種錯誤的時候應該怎么辦呢,myError并未向包外暴露,答案是通過向包外暴露檢查錯誤行為的方法來實現。

  1. myerror.IsXXXError(err)  
  2. ... 

抑或是通過比較error本身與包向外暴露的常量錯誤是否相等來判斷,比如操作文件時常用來判斷文件是否結束的io.EOF。

類似的還有gorm.ErrRecordNotFound等各種開源包對外暴露的錯誤常量。

  1. if err != io.EOF { 
  2.     return err 

錯誤處理常犯的錯誤

先看一段簡單的程序,看大家能不能發現一些細微的問題

  1. func WriteAll(w io.Writer, buf []byte) error { 
  2.     _, err := w.Write(buf) 
  3.     if err != nil { 
  4.         log.Println("unable to write:", err) // annotated error goes to log file 
  5.         return err                           // unannotated error returned to caller 
  6.     } 
  7.     return nil 
  8.  
  9. func WriteConfig(w io.Writer, conf *Config) error { 
  10.     buf, err := json.Marshal(conf) 
  11.     if err != nil { 
  12.         log.Printf("could not marshal config: %v", err) 
  13.         return err 
  14.     } 
  15.     if err := WriteAll(w, buf); err != nil { 
  16.         log.Println("could not write config: %v", err) 
  17.         return err 
  18.     } 
  19.     return nil 
  20.  
  21. func main() { 
  22.     err := WriteConfig(f, &conf) 
  23.     fmt.Println(err) // io.EOF 

錯誤處理常犯的兩個問題

上面程序的錯誤處理暴露了兩個問題:

底層函數WriteAll在發生錯誤后,除了向上層返回錯誤外還向日志里記錄了錯誤,上層調用者做了同樣的事情,記錄日志然后把錯誤再返回給程序頂層。

因此在日志文件中得到一堆重復的內容

  1. unable to write: io.EOF 
  2. could not write config: io.EOF 
  3. ... 

2. 在程序的頂部,雖然得到了原始錯誤,但沒有相關內容,換句話說沒有把WriteAll、WriteConfig記錄到 log 里的那些信息包裝到錯誤里,返回給上層。

針對這兩個問題的解決方案可以是,在底層函數WriteAll、WriteConfig中為發生的錯誤添加上下文信息,然后將錯誤返回上層,由上層程序最后處理這些錯誤。

一種簡單的包裝錯誤的方法是使用fmt.Errorf函數,給錯誤添加信息。

  1. func WriteConfig(w io.Writer, conf *Config) error { 
  2.     buf, err := json.Marshal(conf) 
  3.     if err != nil { 
  4.         return fmt.Errorf("could not marshal config: %v", err) 
  5.     } 
  6.     if err := WriteAll(w, buf); err != nil { 
  7.         return fmt.Errorf("could not write config: %v", err) 
  8.     } 
  9.     return nil 
  10. func WriteAll(w io.Writer, buf []byte) error { 
  11.     _, err := w.Write(buf) 
  12.     if err != nil { 
  13.         return fmt.Errorf("write failed: %v", err) 
  14.     } 
  15.     return nil 

給錯誤附加上下文信息

fmt.Errorf只是給錯誤添加了簡單的注解信息,如果你想在添加信息的同時還加上錯誤的調用棧,可以借助github.com/pkg/errors這個包提供的錯誤包裝能力。

  1. //只附加新的信息 
  2. func WithMessage(err error, message string) error 
  3.  
  4. //只附加調用堆棧信息 
  5. func WithStack(err error) error 
  6.  
  7. //同時附加堆棧和信息 
  8. func Wrap(err error, message string) error 

有包裝方法,就有對應的解包方法,Cause方法會返回包裝錯誤對應的最原始錯誤--即會遞歸地進行解包。

  1. func Cause(err error) error 

下面是使用github.com/pkg/errors改寫后的錯誤處理程序

  1. func ReadFile(path string) ([]byte, error) { 
  2.     f, err := os.Open(path) 
  3.     if err != nil { 
  4.         return nil, errors.Wrap(err, "open failed"
  5.     } 
  6.     defer f.Close() 
  7.     buf, err := ioutil.ReadAll(f) 
  8.     if err != nil { 
  9.         return nil, errors.Wrap(err, "read failed"
  10.     } 
  11.     return buf, nil 
  12. func ReadConfig() ([]byte, error) { 
  13.     home := os.Getenv("HOME"
  14.     config, err := ReadFile(filepath.Join(home, ".settings.xml")) 
  15.     return config, errors.WithMessage(err, "could not read config"
  16.  
  17.  
  18. func main() { 
  19.     _, err := ReadConfig() 
  20.     if err != nil { 
  21.         fmt.Printf("original error: %T %v\n", errors.Cause(err), errors.Cause(err)) 
  22.         fmt.Printf("stack trace:\n%+v\n", err) 
  23.         os.Exit(1) 
  24.     } 

上面格式化字符串時用的 %+v 是在 % v 基礎上,對值進行展開,即展開復合類型值,比如結構體的字段值等明細。

這樣既能給錯誤添加調用棧信息,又能保留對原始錯誤的引用,通過Cause可以還原到最初始引發錯誤的原因。

總結

總結一下,錯誤處理的原則就是:

錯誤只在邏輯的最外層處理一次,底層只返回錯誤。

 

底層除了返回錯誤外,要對原始錯誤進行包裝,增加錯誤信息、調用棧等這些有利于排查的上下文信息。

 

責任編輯:武曉燕 來源: 網管叨bi叨
相關推薦

2021-09-27 15:33:48

Go 開發技術

2020-08-20 10:16:56

Golang錯誤處理數據

2014-11-17 10:05:12

Go語言

2021-04-29 09:02:44

語言Go 處理

2015-08-26 08:31:35

核心程序員成長

2011-04-27 09:21:09

程序員

2015-08-26 09:31:26

程序員建議

2025-06-06 06:45:54

2025-03-31 00:29:44

2021-09-13 07:53:31

Go錯誤處理

2022-09-05 08:55:15

Go2提案語法

2025-06-30 09:49:11

2025-09-05 01:55:00

Go并發錯誤項目

2011-07-13 09:13:56

Android設計

2019-10-30 14:58:45

MVCAndroid表現層

2009-11-26 15:10:08

VS2005資源

2022-12-12 08:53:53

Go版本方式

2023-10-26 15:49:53

Go日志

2020-12-17 06:25:05

Gopanic 模式

2021-09-27 23:28:29

Go多協程并發
點贊
收藏

51CTO技術棧公眾號

亚洲www免费| 黄色av一区二区三区| 久久在线视频免费观看| 7777精品伊人久久久大香线蕉完整版 | 91精品国产综合久久精品图片| 成人午夜免费剧场| 神马一区二区三区| 蜜臀av一级做a爰片久久| 久久av中文字幕| 欧产日产国产精品98| 中文字幕av一区二区三区佐山爱| 亚洲天堂免费看| 极品日韩久久| 国产一区二区女内射| 亚洲三级电影在线观看| 色妞一区二区三区| 日韩av手机在线播放| 亚洲欧美在线综合| 亚洲成人777| 香蕉久久夜色| 午夜视频在线播放| 国产精品资源网站| 国产精品久久999| 日本一区二区三区四区五区| 日韩在线视屏| 亚洲人成电影网站色xx| 一级黄色大片免费看| 欧美日韩国产网站| 欧美视频中文在线看| 国产激情片在线观看| 爱久久·www| 91一区二区在线| 亚洲字幕在线观看| 亚洲午夜激情视频| 人人精品人人爱| 4p变态网欧美系列| 久久久精品国产sm调教网站| 日韩视频在线观看| 亚洲视频日韩精品| 欧美深性狂猛ⅹxxx深喉| 亚洲精品午夜| 91精品国产综合久久婷婷香蕉| 国产无套粉嫩白浆内谢的出处| av中文在线资源库| 一区二区三区资源| 在线一区日本视频| av网站在线免费观看| 91视频xxxx| 国产视频一区二区不卡| 不卡的日韩av| 国产乱人伦精品一区二区在线观看 | 婷婷色一区二区三区| 色天下一区二区三区| 日韩手机在线导航| 午夜影院免费观看视频| www.久久99| 91麻豆精品国产无毒不卡在线观看| 欧美日韩在线成人| 色综合天天色| 欧美性色欧美a在线播放| 成年人小视频网站| 一二区成人影院电影网| 欧洲一区二区三区在线| 日韩视频免费在线播放| 日韩一区二区三区免费视频| 色噜噜久久综合| 2022亚洲天堂| 日韩电影免费观看高清完整版| 图片区小说区国产精品视频| aa在线观看视频| 亚洲男人av| 欧美日韩亚洲视频一区| 成人性视频欧美一区二区三区| 亚洲精品在线影院| 欧美日韩国产大片| 成年人性生活视频| 久久精品亚洲成在人线av网址| 亚洲激情视频在线播放| 国产全是老熟女太爽了| 日韩大片在线播放| 超在线视频97| 日本三级视频在线| 久久久精品性| 成人久久精品视频| 亚洲精品97久久中文字幕| av日韩在线网站| 视频一区二区在线观看| a视频在线观看免费| 亚洲国产sm捆绑调教视频| 欧美xxxxx在线视频| 五月天色综合| 亚洲国产成人爱av在线播放| 欧美黄色一级生活片| 91av精品| 欧洲亚洲在线视频| 国产裸体无遮挡| 95精品视频在线| 亚洲欧洲精品一区| 成人免费高清观看| 欧美日精品一区视频| 男人添女人荫蒂国产| 国内精品久久久久久99蜜桃| 操人视频在线观看欧美| 国产精品久久久久久人| 国产精品88888| 日韩欧美亚洲区| 国产白丝在线观看| 欧美喷潮久久久xxxxx| 国产精品九九视频| 天天操综合网| 欧美一级淫片播放口| 99久久婷婷国产一区二区三区| 99精品1区2区| 97av中文字幕| 欧美美女福利视频| 亚洲全黄一级网站| 青青草av在线播放| 国产suv精品一区二区883| 日韩欧美亚洲v片| 中文在线аv在线| 日韩一区二区精品在线观看| 国产精品天天干| 99在线精品视频在线观看| 92福利视频午夜1000合集在线观看 | 国产熟女一区二区| 99热这里只有成人精品国产| 91精品一区二区| 国产日本在线观看| 欧美性jizz18性欧美| 97精品人人妻人人| 久久视频国产| 国产精品爱久久久久久久| 天天摸夜夜添狠狠添婷婷| 一区二区三区在线视频免费| 女人高潮一级片| 欧洲视频一区| 国产99久久精品一区二区永久免费 | 午夜dj在线观看高清视频完整版| 欧美写真视频网站| 亚洲图片另类小说| 久久精品官网| 欧美亚洲一级二级| 亚洲天堂av在线| 精品国产伦理网| 久久网中文字幕| 国产精品系列在线观看| 国产欧美综合一区| **国产精品| 色诱女教师一区二区三区| 中文字幕 国产精品| 久久久精品欧美丰满| 99精品视频在线看| 国产成人短视频在线观看| 日本精品一区二区三区在线播放视频 | 玖玖精品视频| 奇米视频888战线精品播放| 26uuu亚洲电影| 亚洲欧美三级在线| 啪啪小视频网站| 国产欧美精品一区二区色综合朱莉 | 国产男男chinese网站| 亚洲视频大全| 欧美连裤袜在线视频| 久久sese| 中文字幕日韩精品有码视频| 中文字幕一区二区久久人妻| 中文欧美字幕免费| 天堂视频免费看| 你懂的亚洲视频| 国产精品播放| 最新欧美色图| 中文字幕亚洲自拍| 国产精品久久久久久久久久久久久久久久久久 | 伊人网伊人影院| 奇米影视7777精品一区二区| 一区二区冒白浆视频| 精品中文字幕一区二区三区四区 | 免费久久99精品国产自| 亚洲承认视频| 在线一区二区日韩| 国产一区二区三区视频免费观看| 亚洲精品一二三四区| 国产精品91av| 久久av最新网址| 在线电影看在线一区二区三区| 美女久久精品| 欧美亚洲在线观看| 男人影院在线观看| 日韩女同互慰一区二区| 国产成人综合欧美精品久久| 中文字幕第一区第二区| 久久久久亚洲av无码专区首jn| 亚洲日本欧美| 一区二区三区av在线| 成人影院中文字幕| 国产精品视频精品视频| 日本精品600av| 一本大道久久加勒比香蕉| 国内精品久久久久久久久久久| 精品久久久久久中文字幕一区奶水 | 中文字幕国产日韩| 超碰在线人人干| 欧美亚一区二区| 老女人性淫交视频| 久久久91精品国产一区二区精品| а 天堂 在线| 久久精品亚洲| 国产欧美日韩小视频| 欧美日韩中文一区二区| 高清av免费一区中文字幕| 欧亚一区二区| 午夜精品一区二区三区av| 91在线直播| 亚洲精品mp4| 国产视频aaa| 欧美亚洲国产bt| 欧美日韩成人免费观看| 久久综合狠狠综合久久综合88 | 伊人亚洲精品| 91成人免费观看网站| av影片免费在线观看| 国产视频久久久久| 狠狠躁夜夜躁av无码中文幕| 欧美精品在线观看一区二区| 黄色免费av网站| 亚洲国产精品欧美一二99| 久久噜噜色综合一区二区| 久久久一区二区| 三级男人添奶爽爽爽视频| 国产成人8x视频一区二区| 精品日韩久久久| 天堂成人国产精品一区| 妞干网在线视频观看| 欧美日韩一区二区国产| 黑人巨大国产9丨视频| 日韩精品久久| 性欧美videosex高清少妇| 自拍亚洲一区| 久久综合毛片| 三级小说欧洲区亚洲区| 极品日韩久久| 日韩精品福利一区二区三区| 高清视频一区| 成人性生交大片免费看96| 波多野结衣成人在线| 视频成人永久免费视频| 亚洲一区久久久| 精品国产麻豆| 99中文字幕| www.丝袜精品| 国产麻豆日韩| av毛片精品| 好看的日韩精品| 国产一区二区在线视频你懂的| 国产精品久久九九| 久久黄色影视| 日本中文不卡| 全球成人免费直播| 一区二区三区四区免费视频| 国产精品久久天天影视| 国产高清免费在线| 欧美日本不卡| 每日在线观看av| 亚洲精选91| 色婷婷综合久久久久中文字幕| 三级在线观看一区二区| 深夜黄色小视频| 国产中文一区二区三区| 青娱乐精品在线| 99免费精品在线| 国产jk精品白丝av在线观看| 欧美国产丝袜视频| 天天操天天操天天操天天操天天操| 亚洲少妇屁股交4| 久久久久久久福利| 欧美日韩在线视频首页| 国产第一页在线观看| 在线不卡a资源高清| 国内老熟妇对白xxxxhd| 亚洲精品国产综合久久| 番号集在线观看| 插插插亚洲综合网| 亚洲深夜视频| 国产欧美一区二区三区久久| 日韩中文一区二区| 欧美日韩综合网| 婷婷综合网站| 日韩在线综合网| 免费人成在线不卡| 中国特级黄色片| 国产午夜精品一区二区| 久久久久亚洲AV成人| 天天av天天翘天天综合网色鬼国产| 国产精品成人久久久| 91精品国产乱码| 日漫免费在线观看网站| 久久久国产成人精品| 小h片在线观看| 亚洲一区中文字幕在线观看| 欧美精品中文字幕亚洲专区| 亚洲综合激情五月| 亚洲欧美日韩视频二区| 亚洲欧美天堂在线| 久久久国产精华| 国产一级视频在线| 欧美在线免费观看视频| 六月婷婷中文字幕| 日韩中文字幕免费| 自拍网站在线观看| 国产成人精品免费视频大全最热 | 白嫩亚洲一区二区三区| 免费看污久久久| 欧美日韩国产亚洲一区| 一区二区三区免费播放| 99re成人精品视频| 欧美三级免费看| 欧美日韩成人在线| 日韩电影网址| 欧美激情欧美激情| 99久久99九九99九九九| 无遮挡亚洲一区| 国产精品毛片| 88av在线播放| 亚洲精品老司机| 亚洲一区在线观| 亚洲天堂av女优| 蜜桃视频www网站在线观看| 91黄在线观看| 亚洲情侣在线| 亚洲va在线va天堂va偷拍| 国产日韩视频一区二区三区| 国产精品100| 精品va天堂亚洲国产| 先锋影音在线资源站91| 成人免费看片视频| 久久中文亚洲字幕| 中文字幕av专区| 国产欧美一区二区精品仙草咪 | 在线成人免费视频| 又爽又大又黄a级毛片在线视频| 欧美壮男野外gaytube| 久久男人av| av动漫在线看| 97久久超碰精品国产| 日本一区二区三区免费视频| 亚洲丁香婷深爱综合| 678在线观看视频| 国产精品sss| 99亚洲一区二区| 3d动漫精品啪啪一区二区下载| 欧美性高潮床叫视频| 你懂的在线网址| 国产精品久久国产精品99gif| 国产欧美日韩在线一区二区| 麻豆传传媒久久久爱| 久久精品视频免费观看| 日本免费精品视频| 色偷偷偷综合中文字幕;dd| 亚洲美女色播| 国产树林野战在线播放| 国产精品一区二区三区99| 欧美精品色哟哟| 精品视频www| 丝袜美腿一区| 一区二区三区的久久的视频| 国内精品视频一区二区三区八戒| 侵犯稚嫩小箩莉h文系列小说| 欧美一区二区三区公司| 超免费在线视频| 久久精品国产精品国产精品污| 免费在线亚洲| 18精品爽国产三级网站| 3d动漫精品啪啪一区二区竹菊 | 欧美视频一二区| 欧美在线视频免费| 日韩一区二区在线| 亚洲乱妇老熟女爽到高潮的片| 午夜视频在线观看一区| 国产在线三区| 亚洲综合最新在线| 国产视频欧美| av在线免费播放网址| 欧美电影免费观看完整版| 欧美久久天堂| 一区二区三区三区在线| 成人精品一区二区三区中文字幕| 成人午夜淫片100集| 精品国产一区二区三区在线观看| 视频一区日韩精品| 欧美牲交a欧美牲交aⅴ免费真 | 日韩成人高清| 青青草综合在线| 久久先锋影音av| 国产xxxxxx| 日韩av大片免费看| 综合色一区二区| 性欧美成人播放77777| 欧美精品粉嫩高潮一区二区| 美女在线视频免费| 中文字幕av日韩精品|