成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Go項目Error的統一規劃管理和處理策略

開發 項目管理
如果每一層都打日志,查詢日志的時候必然會有不少重復,當然這個見仁見智,多打點日志也沒錯總比不打日志,出問題了再打日志,等線上復現問題后再排查日志要強多了。

這一篇文章我們來探討一下怎么在項目初期提前規劃,把項目的各種Error統一管理起來,以及寫代碼遇到Error時在不同的代碼層我們應該怎么處理它們。

圖片圖片


怎么把項目的Error管理起來

在聊怎么把Error管理起來之前我們先來聊一下為什么要管理Error,有Error就有Error唄,把信息返回給調用者不就行了?這里說的調用者指的是請求我們系統API的調用方。

乍一想好像確實沒毛病,但是咱們把眼光放到團隊開發和對接上。

其一:與咱們對接的系統,判斷錯誤一般靠的都是錯誤響應里的Code碼,如果同一個類型的錯誤你返回不同的錯誤碼,一兩個還好,如果十個八個估計對方就要過來找你們算帳了。

其二:既然一類錯誤的錯誤碼要統一,那每次都自己NewError再設置它的錯誤碼,這樣即使只有一個人開發這個項目,次數多了也會把錯誤碼寫錯的,更別提多個人一起開發的時候了。

所以就需要我們先把常見的能想到的錯誤預先定義出來。這也就是為什么咱們的項目在error模塊的code.go中預先定義了下面幾個基礎的錯誤。

var (
 Success            = newError(0, "success")
 ErrServer          = newError(10000000, "服務器內部錯誤")
 ErrParams          = newError(10000001, "參數錯誤, 請檢查")
 ErrNotFound        = newError(10000002, "資源未找到")
 ErrPanic           = newError(10000003, "(*^__^*)系統開小差了,請稍后重試") // 無預期的panic錯誤
 ErrToken           = newError(10000004, "Token無效")
 ErrForbidden       = newError(10000005, "未授權") // 訪問一些未授權的資源時的錯誤
 ErrTooManyRequests = newError(10000006, "請求過多")
 ErrCoverData       = newError(10000007, "ConvertDataError") // 數據轉換錯誤
)

除了這些通用的錯誤之外,我們可以預先按照項目的模塊分配每個業務模塊錯誤的碼段。比如在未來的項目代碼中你會看到一些給業務模塊單獨定義的錯誤碼。

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

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

// 購物車模塊相關錯誤碼 10000300 ~ 1000399
var (
 ErrCartItemParam = newError(10000300, "購物項參數異常")
 ErrCartWrongUser = newError(10000301, "用戶購物信息不匹配")
  ...
)

到這里一直說的都是預先定義錯誤,那針對一些不知道什么類型的錯誤該怎么辦?比如在DAO層做了一下CRUD出現了Error,難道還要預先定義一個ErrDBQuery 之類的錯誤嗎?那項目用的中間件多了,Redis、MQ什么的都要預先定義錯誤嗎?

這里我給我的方案是,調用其他外部基礎組件出錯時,調用一個SDK方法出錯時,把底層錯誤包裝成項目的Error。

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

當你拿到一個error不確定它該是什么錯誤,你就用這個Wrap方法包裝成項目的App Error。

下一節我們封裝的統一接口響應組件會使用下面的方法來獲取Error對應的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

我們在寫代碼的時候為了保險,都愛在 error 判斷中打一條Error級別的日志,這樣好歹遇到錯誤了在日志中會留下痕跡,到了真需要排除問題的時候總比那些什么日志都不記錄的寫法要好多了。

很多時候我們遇到線上問題了,查半天最后實現沒辦法就加幾條日志部署上去觀察觀察情況,等同樣的錯誤發生了再去看新打的日志。

但是不知道大家有沒有發現,如果你每遇到Error都打一條日志的話,那么這個錯誤信息在日志里的重復率時相當的高,發生了一個錯誤,好幾條日志都是這個錯誤信息,其實都是同一個錯誤,只不過這些日志是在調用邏輯的不同代碼層做被打進去的。

那么關于什么錯誤該記日志,什么不該記,有沒有什么好用的標準?不好意思沒有,全靠自己的悟性。。。。。。聽到這里是不是想罵人了。

這里分享一下國外論壇中經常看到的 Only handle errors once的原則

Go程序錯誤處理的原則:

  • 程序底層 (Dao、基礎設施層) 拋出錯誤
  • 程序中層(領域服務層、應用服務層)包裝錯誤
  • 程序上層(控制層) 記錄錯誤

如果每一層都打日志,查詢日志的時候必然會有不少重復,當然這個見仁見智,多打點日志也沒錯總比不打日志,出問題了再打日志,等線上復現問題后再排查日志要強多了。

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

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

2024-12-11 09:13:00

2023-11-28 14:32:04

2021-01-07 15:22:06

智能交通智能網聯

2024-11-04 09:02:51

Go項目接口

2009-08-25 16:47:32

統一通信視頻會議策略規劃

2021-09-08 09:41:09

開發Go代碼

2016-11-15 09:44:21

大數據批處理流處理

2010-12-21 18:07:39

2024-11-06 09:23:32

2009-05-09 09:25:08

思科UCS產品

2025-03-31 00:29:44

2011-09-21 10:21:11

網絡管理網絡規劃無線網絡

2010-12-27 15:22:47

組策略

2011-08-25 15:16:52

電子政務政府IA服務器

2022-07-27 16:36:29

node.js前端

2011-10-19 09:57:11

2024-10-28 09:04:38

Go項目客戶端

2022-05-07 10:09:01

開發Java日志

2025-02-26 09:03:24

2020-07-10 08:07:29

機器學習
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久精品国产亚洲一区二区三区 | 免费一区 | 91在线视频免费观看 | 亚洲成人一区二区三区 | 妞干网视频 | 国产专区在线 | 国产精品久久久久久久粉嫩 | 精品久久久网站 | 欧美国产精品一区二区三区 | 欧美极品视频 | 天天综合国产 | 欧美精品一二三区 | 国产精品爱久久久久久久 | 日韩欧美视频 | 精精国产xxxx视频在线野外 | 干干干操操操 | 欧美精品一二三 | 久久婷婷国产香蕉 | 亚洲综合大片69999 | 成人在线精品视频 | 日韩国产在线观看 | 欧美综合国产精品久久丁香 | 久久高清免费视频 | www.日韩 | 国产精品成人一区二区三区吃奶 | 久久久蜜臀国产一区二区 | 国产精品亚洲精品日韩已方 | 国产精品99久久久久 | 男人天堂999 | 精品国产乱码久久久久久老虎 | 国产一区二区三区四区在线观看 | 欧美成人一级 | 天堂网av在线| 最新中文字幕在线播放 | 99免费在线观看视频 | 国产区一区 | 中文字幕在线第一页 | 国产成人免费视频网站视频社区 | 国产精品毛片一区二区在线看 | 免费在线观看成人 | 国产精品天堂 |