自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Go項(xiàng)目Error的統(tǒng)一規(guī)劃管理和處理策略

開發(fā) 項(xiàng)目管理
如果每一層都打日志,查詢?nèi)罩镜臅r(shí)候必然會(huì)有不少重復(fù),當(dāng)然這個(gè)見仁見智,多打點(diǎn)日志也沒(méi)錯(cuò)總比不打日志,出問(wèn)題了再打日志,等線上復(fù)現(xiàn)問(wèn)題后再排查日志要強(qiáng)多了。

這一篇文章我們來(lái)探討一下怎么在項(xiàng)目初期提前規(guī)劃,把項(xiàng)目的各種Error統(tǒng)一管理起來(lái),以及寫代碼遇到Error時(shí)在不同的代碼層我們應(yīng)該怎么處理它們。

圖片圖片


怎么把項(xiàng)目的Error管理起來(lái)

在聊怎么把Error管理起來(lái)之前我們先來(lái)聊一下為什么要管理Error,有Error就有Error唄,把信息返回給調(diào)用者不就行了?這里說(shuō)的調(diào)用者指的是請(qǐng)求我們系統(tǒng)API的調(diào)用方。

乍一想好像確實(shí)沒(méi)毛病,但是咱們把眼光放到團(tuán)隊(duì)開發(fā)和對(duì)接上。

其一:與咱們對(duì)接的系統(tǒng),判斷錯(cuò)誤一般靠的都是錯(cuò)誤響應(yīng)里的Code碼,如果同一個(gè)類型的錯(cuò)誤你返回不同的錯(cuò)誤碼,一兩個(gè)還好,如果十個(gè)八個(gè)估計(jì)對(duì)方就要過(guò)來(lái)找你們算帳了。

其二:既然一類錯(cuò)誤的錯(cuò)誤碼要統(tǒng)一,那每次都自己NewError再設(shè)置它的錯(cuò)誤碼,這樣即使只有一個(gè)人開發(fā)這個(gè)項(xiàng)目,次數(shù)多了也會(huì)把錯(cuò)誤碼寫錯(cuò)的,更別提多個(gè)人一起開發(fā)的時(shí)候了。

所以就需要我們先把常見的能想到的錯(cuò)誤預(yù)先定義出來(lái)。這也就是為什么咱們的項(xiàng)目在error模塊的code.go中預(yù)先定義了下面幾個(gè)基礎(chǔ)的錯(cuò)誤。

var (
 Success            = newError(0, "success")
 ErrServer          = newError(10000000, "服務(wù)器內(nèi)部錯(cuò)誤")
 ErrParams          = newError(10000001, "參數(shù)錯(cuò)誤, 請(qǐng)檢查")
 ErrNotFound        = newError(10000002, "資源未找到")
 ErrPanic           = newError(10000003, "(*^__^*)系統(tǒng)開小差了,請(qǐng)稍后重試") // 無(wú)預(yù)期的panic錯(cuò)誤
 ErrToken           = newError(10000004, "Token無(wú)效")
 ErrForbidden       = newError(10000005, "未授權(quán)") // 訪問(wèn)一些未授權(quán)的資源時(shí)的錯(cuò)誤
 ErrTooManyRequests = newError(10000006, "請(qǐng)求過(guò)多")
 ErrCoverData       = newError(10000007, "ConvertDataError") // 數(shù)據(jù)轉(zhuǎn)換錯(cuò)誤
)

除了這些通用的錯(cuò)誤之外,我們可以預(yù)先按照項(xiàng)目的模塊分配每個(gè)業(yè)務(wù)模塊錯(cuò)誤的碼段。比如在未來(lái)的項(xiàng)目代碼中你會(huì)看到一些給業(yè)務(wù)模塊單獨(dú)定義的錯(cuò)誤碼。

// 用戶模塊相關(guān)錯(cuò)誤碼 10000100 ~ 1000199
var (
 ErrUserInvalid      = newError(10000101, "用戶異常")
 ErrUserNameOccupied = newError(10000102, "用戶名已被占用")
  ...
)

// 商品模塊相關(guān)錯(cuò)誤碼 10000200 ~ 1000299
var (
 ErrCommodityNotExists = newError(10000200, "商品不存在")
 ErrCommodityStockOut  = newError(10000201, "庫(kù)存不足")
  ...
)

// 購(gòu)物車模塊相關(guān)錯(cuò)誤碼 10000300 ~ 1000399
var (
 ErrCartItemParam = newError(10000300, "購(gòu)物項(xiàng)參數(shù)異常")
 ErrCartWrongUser = newError(10000301, "用戶購(gòu)物信息不匹配")
  ...
)

到這里一直說(shuō)的都是預(yù)先定義錯(cuò)誤,那針對(duì)一些不知道什么類型的錯(cuò)誤該怎么辦?比如在DAO層做了一下CRUD出現(xiàn)了Error,難道還要預(yù)先定義一個(gè)ErrDBQuery 之類的錯(cuò)誤嗎?那項(xiàng)目用的中間件多了,Redis、MQ什么的都要預(yù)先定義錯(cuò)誤嗎?

這里我給我的方案是,調(diào)用其他外部基礎(chǔ)組件出錯(cuò)時(shí),調(diào)用一個(gè)SDK方法出錯(cuò)時(shí),把底層錯(cuò)誤包裝成項(xiàng)目的Error。

func Wrap(msg string, err error) *AppError {
 if err == nil {
  return nil
 }
 appErr := &AppError{code: -1, msg: msg, cause: err}
 return appErr
}

當(dāng)你拿到一個(gè)error不確定它該是什么錯(cuò)誤,你就用這個(gè)Wrap方法包裝成項(xiàng)目的App Error。

下一節(jié)我們封裝的統(tǒng)一接口響應(yīng)組件會(huì)使用下面的方法來(lái)獲取Error對(duì)應(yīng)的HTTP Code。

func (e *AppError) HttpStatusCode() int {
 switch e.Code() {
 case Success.Code():
  return http.StatusOK
 case ErrParams.Code():
  return http.StatusBadRequest
 case ErrNotFound.Code():
 ......
 default:
  return http.StatusInternalServerError
 }
}

不同代碼層該怎么處理Error

我們?cè)趯懘a的時(shí)候?yàn)榱吮kU(xiǎn),都愛(ài)在 error 判斷中打一條Error級(jí)別的日志,這樣好歹遇到錯(cuò)誤了在日志中會(huì)留下痕跡,到了真需要排除問(wèn)題的時(shí)候總比那些什么日志都不記錄的寫法要好多了。

很多時(shí)候我們遇到線上問(wèn)題了,查半天最后實(shí)現(xiàn)沒(méi)辦法就加幾條日志部署上去觀察觀察情況,等同樣的錯(cuò)誤發(fā)生了再去看新打的日志。

但是不知道大家有沒(méi)有發(fā)現(xiàn),如果你每遇到Error都打一條日志的話,那么這個(gè)錯(cuò)誤信息在日志里的重復(fù)率時(shí)相當(dāng)?shù)母?,發(fā)生了一個(gè)錯(cuò)誤,好幾條日志都是這個(gè)錯(cuò)誤信息,其實(shí)都是同一個(gè)錯(cuò)誤,只不過(guò)這些日志是在調(diào)用邏輯的不同代碼層做被打進(jìn)去的。

那么關(guān)于什么錯(cuò)誤該記日志,什么不該記,有沒(méi)有什么好用的標(biāo)準(zhǔn)?不好意思沒(méi)有,全靠自己的悟性。。。。。。聽到這里是不是想罵人了。

這里分享一下國(guó)外論壇中經(jīng)??吹降?nbsp;Only handle errors once的原則

Go程序錯(cuò)誤處理的原則:

  • 程序底層 (Dao、基礎(chǔ)設(shè)施層) 拋出錯(cuò)誤
  • 程序中層(領(lǐng)域服務(wù)層、應(yīng)用服務(wù)層)包裝錯(cuò)誤
  • 程序上層(控制層) 記錄錯(cuò)誤

如果每一層都打日志,查詢?nèi)罩镜臅r(shí)候必然會(huì)有不少重復(fù),當(dāng)然這個(gè)見仁見智,多打點(diǎn)日志也沒(méi)錯(cuò)總比不打日志,出問(wèn)題了再打日志,等線上復(fù)現(xiàn)問(wèn)題后再排查日志要強(qiáng)多了。

還有一個(gè)原因就是Go的原生 Error 如果你不自己做自定義封裝確實(shí)能給咱們的有效信息很少,我們看到錯(cuò)誤信息經(jīng)常是找半天才能找到原因。

責(zé)任編輯:武曉燕 來(lái)源: 網(wǎng)管叨bi叨
相關(guān)推薦

2024-12-11 09:13:00

2023-11-28 14:32:04

2024-11-04 09:02:51

Go項(xiàng)目接口

2009-08-25 16:47:32

統(tǒng)一通信視頻會(huì)議策略規(guī)劃

2021-09-08 09:41:09

開發(fā)Go代碼

2021-01-07 15:22:06

智能交通智能網(wǎng)聯(lián)

2024-11-06 09:23:32

2016-11-15 09:44:21

大數(shù)據(jù)批處理流處理

2010-12-21 18:07:39

2011-09-21 10:21:11

網(wǎng)絡(luò)管理網(wǎng)絡(luò)規(guī)劃無(wú)線網(wǎng)絡(luò)

2009-05-09 09:25:08

思科UCS產(chǎn)品

2025-03-31 00:29:44

2010-12-27 15:22:47

組策略

2022-07-27 16:36:29

node.js前端

2024-10-28 09:04:38

Go項(xiàng)目客戶端

2011-08-25 15:16:52

電子政務(wù)政府IA服務(wù)器

2011-10-19 09:57:11

2025-02-26 09:03:24

2022-05-07 10:09:01

開發(fā)Java日志

2020-07-10 08:07:29

機(jī)器學(xué)習(xí)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)