錯誤碼如何設計才合理?

来源:https://www.cnblogs.com/88223100/archive/2022/11/06/How-to-design-the-error-code-reasonably.html
-Advertisement-
Play Games

導讀:對於錯誤碼的設計,不同的開發團隊有不同的風格習慣。本文分享阿裡文娛技術專家長統對於錯誤碼的看法,希望從錯誤碼使用的不同場景討論得到一個合理的錯誤碼規約,得到一個面嚮日志錯誤碼標準和一個面向外部傳遞的錯誤碼標準。 ...


 

 

導讀:對於錯誤碼的設計,不同的開發團隊有不同的風格習慣。本文分享阿裡文娛技術專家長統對於錯誤碼的看法,希望從錯誤碼使用的不同場景討論得到一個合理的錯誤碼規約,得到一個面嚮日志錯誤碼標準和一個面向外部傳遞的錯誤碼標準。


一  前言
在工作中,接觸過不少外部介面,其中包括:支付寶,微信支付,微博開發平臺,阿裡雲等等。每家公司錯誤碼風格都不盡相同,有使用純數字的,有使用純英文的,也有使用字母和數字組合的。也接觸過很多內部系統,錯誤碼設計也不盡相同。
錯誤碼的輸出路徑
面嚮日志輸出

  • 服務內傳遞,最終是輸出到日誌。

 

  • 域內服務間,比如同時大麥電商之間的系統,最終目的是輸出到日誌。


面向外部傳遞

  • 域內向域外

  • 服務端傳遞到前端

  • OpenAPI 錯誤碼

  • 內部不同域之間


錯誤碼使用場景

  • 通過錯誤碼配置監控大盤。

  • 通過日誌進行問題排查,快速定位問題。

  • 後端服務之間錯誤碼傳遞。

  • 前端展示的錯誤提示/OpenAPI。


本文希望從錯誤碼使用的不同場景討論得到一個合理的錯誤碼規約,得到一個面嚮日志錯誤碼標準和一個面向外部傳遞的錯誤碼標準。
PS:本文引用全部引自阿裡巴巴《Java 開發手冊》,下稱《手冊》。


二  什麼是錯誤碼
錯誤碼要回答的最根本的問題是,誰的錯?錯在哪?
那麼一個錯誤能表示出誰的錯和錯在哪裡就是一個好的錯誤碼嗎?答案顯然是否定的,這個標準太基礎了。

  • 好的錯誤碼必須能夠快速知曉錯誤來源。

 

  • 好的錯誤碼必須易於記憶和對比。

 

  • 好的錯誤碼必須能夠脫離文檔和系統平臺達到線下輕量溝通的目的(這個要求比較高)。


引自《手冊》- 異常日誌-錯誤碼

錯誤碼的制定原則:快速溯源、簡單易記、溝通標準化。
說明:錯誤碼想得過於完美和複雜,就像康熙字典中的生僻字一樣,用詞似乎精準,但是字典不容易隨身攜帶並且簡單易懂。
正例:錯誤碼回答的問題是誰的錯?錯在哪?
1)錯誤碼必須能夠快速知曉錯誤來源,可快速判斷是誰的問題。
2)錯誤碼易於記憶和比對(代碼中容易 equals)。
3)錯誤碼能夠脫離文檔和系統平臺達到線下輕量化地自由溝通的目的。 


這個原則寫在異常日誌-錯誤碼這個章節,我認為同樣適用在面向用戶的錯誤碼。

 

 


三  錯誤碼規範
錯誤碼定義要有字母也要有數字
純數字錯誤碼

錯誤碼即人性,感性認知+口口相傳,使用純數字來進行錯誤碼編排不利於感性記憶和分類。
說明:數字是一個整體,每位數字的地位和含義是相同的。
反例:一個五位數字 12345,第1位是錯誤等級,第 2 位是錯誤來源,345 是編號,人的大腦不會主動地分辨每位數字的不同含義。


《手冊》說明瞭純數字錯誤碼存在的問題。
純字母錯誤碼
那麼純字母錯誤碼不香嗎?有兩個問題:

  • 對於使用漢語的我們用英語去準確描述一個錯誤有時是比較困難的。

 

  • 純英文字母的錯誤碼不利於排序。

 

錯誤碼儘量有利於不同文化背景的開發者進行交流與代碼協作。
說明:英文單詞形式的錯誤碼不利於非英語母語國家(如阿拉伯語、希伯來語、俄羅斯語等)之間的開發者互相協作。


快速溯源 | 簡單易記 | 溝通標準化
什麼是快速溯源?就是一眼看上去就知道哪裡出了什麼問題。
李雷負責 A 服務,韓梅梅負責 B 服務。韓梅梅發現服務 B 出現了一個錯誤碼,韓梅梅能夠快速定位這是服務 A 的內部業務異常造成的問題,這個時候韓梅梅就可以拿著錯誤碼找到李雷說,"hi,Li Lei,How old are you。(李雷,怎麼老是你)"。李雷拿過來錯誤碼一看,內心萬馬奔騰,一下就能知道這是上游 Polly 負責的應用阿爾法出了錯。
怎麼能達到這個效果呢?

  • 首先要有一套標準並且在域內各個業務都在用同樣的標準。

  • 其次要求錯誤碼有自我解釋的能力是有信息含量的有意義。

  • 最後在域內要傳遞錯誤碼。


錯誤碼標準的意義
開宗明義借用了《手冊》對於錯誤碼定義的原則作為錯誤碼規範能夠給我們帶來的收益。我想再次強調並且試著從反面闡述沒有錯誤碼標準會帶來的成本。
錯誤碼是用來做溝通的:系統與系統間的溝通,人與人間的溝通,人與系統間的溝通。
試想下麵這個場景:
韓梅梅看到一個異常日誌其中一個純數字的錯誤碼。
韓梅梅需要理解這串數字代表的是什麼,它到底是不是一個錯誤碼,經過幾秒鐘確定下來這是一個錯誤碼,但她不能確定這是不是本系統中錯誤碼,因為在她負責的系統是由韓梅梅、Lucy 和 Lily 三個人共同維護的,每個人都按照自己的理解定義了一套錯誤碼。
韓梅梅去系統源碼中查找這個錯誤碼,但是發現這個錯誤碼並不是本系統的錯誤碼。
然後再前翻兩頁後翻兩頁從日誌上下文中確定這是李雷負責系統的錯誤碼,“Li Lie,how old are you?”。
韓梅梅把錯誤碼甩到李雷臉上,李雷一臉懵逼,這是我的系統的錯誤碼嗎?
李雷也不確定,因為李雷負責的系統是由李雷、林濤和 Jim 維護的,也是三人共同維護的。
李雷只好打開源碼,還真是!
上邊的場景經過了發現-初判斷-判斷來源-確定來源-溝通-二次判斷-二次確認七個步驟。
希望上邊的場景描述能夠說明沒有統一標準的錯誤所帶來的成本。


四  面嚮日志的錯誤碼
輸出到日誌的錯誤碼有兩個用途:

  • 用來快速溯源找到問題。

  • 用來形成監控大盤。


錯誤碼設計
《手冊》對於錯誤碼的建議有非常多的可取參考的地方:

錯誤碼不體現版本號和錯誤等級信息。
說明:錯誤碼以不斷追加的方式進行相容。錯誤等級由日誌和錯誤碼本身的釋義來決定。 

 

錯誤碼為字元串類型,共 5 位,分成兩個部分:錯誤產生來源+四位數字編號。

 

錯誤碼不能直接輸出給用戶作為提示信息使用。
說明:堆棧(stack_trace)、錯誤信息(error_message)、錯誤碼(error_code)、提示信息(user_tip)是一個有效關聯並互相轉義的和諧整體,但是請勿互相越俎代庖。

 

在獲取第三方服務錯誤碼時,向上拋出允許本系統轉義,由 C 轉為 B,並且在錯誤信息上帶上原有的第三方錯誤碼。 
結合錯誤碼設計原則、錯誤碼用途、規約建議,面向服務端日誌的錯誤碼應該是如下形式。

 

錯誤碼分為一級巨集觀錯誤碼、二級巨集觀錯誤碼、三級巨集觀錯誤碼。 

 

錯誤碼即人性,感性認知+口口相傳,使用純數字來進行錯誤碼編排不利於感性記憶和分類。
說明:數字是一個整體,每位數字的地位和含義是相同的。
反例:一個五位數字 12345,第 1 位是錯誤等級,第 2 位是錯誤來源,345 是編號,人的大腦不會主動地分辨每位數字的不同含義。


按照《手冊》的建議設計出的面嚮日志的錯誤碼定義共十三位(十位有意義,三位連接符),並且應該具有如下分類:

  • 應用標識,表示錯誤屬於哪個應用,三位數字。

  • 功能域標識,表示錯誤屬於應用中的哪個功能模塊,三位數字。

  • 錯誤類型,表示錯誤屬於那種類型,一位字母。

  • 錯誤編碼,錯誤類型下的具體錯誤,三位數字。



《手冊》還有一條是規定錯誤碼應該如何定義:

錯誤碼為字元串類型,共 5 位,分成兩個部分:錯誤產生來源+四位數字編號。
說明:錯誤產生來源分為 A/B/C,A 表示錯誤來源於用戶,比如參數錯誤,用戶安裝版本過低,用戶支付超時等問題;B 表示錯誤來源於當前系統,往往是業務邏輯出錯,或程式健壯性差等問題;C 表示錯誤來源於第三方服務,比如 CDN 服務出錯,消息投遞超時等問題;四位數字編號從 0001 到 9999,大類之間的步長間距預留 100。


五位錯誤碼的好處是易記,但是對於面嚮日志的錯誤碼場景利用錯誤碼製作需要分類的業務監控大盤將變得比較困難,比如統計應用 A 的功能 B 的錯誤出現次數。
同樣在系統間傳遞這個類型的錯誤碼非常有可能發生錯誤碼衝突。
當然對於分為四段的錯誤碼同樣尤其不好的一面,應用標識和功能域標識需要有專人去管理或者開發一個錯誤碼管理工具,否則時間一長很容易產生定義的混亂形成破窗。
《手冊》對於錯誤碼定義我認為非常適合面向外部傳遞的錯誤碼。簡單、易記、是大家熟悉的錯誤碼樣式,並且透出的錯誤碼數量是非常有限的。
不用枚舉定義錯誤碼
國際化支持是一個不使用枚舉定義錯誤碼很重要的理由。
我們通過 i18n 的支持可以做到錯誤碼、錯誤狀態、錯誤描述的管理。


五  面向外部傳遞的錯誤碼
面向外部傳遞的錯誤碼是為了把域內的錯誤信息傳遞出去。
可以讓域外系統通過錯誤碼進行錯誤碼進行後續的動作或是中斷操作或是記錄日誌繼續執行。
可以讓前端通過錯誤碼給出用戶準確的錯誤提示或者忽略錯誤進行重試。
錯誤碼設計
根據《手冊》給出的錯誤碼定義建議設計出的面向外部傳遞的錯誤碼共五位,並且有如下分類:

  • 錯誤類型,表示錯誤來源,一位字母。

  • 錯誤編碼,表示具體錯誤,四位數字。


錯誤碼的後三位編號與 HTTP 狀態碼沒有任何關係。 

 

錯誤碼即人性,感性認知+口口相傳,使用純數字來進行錯誤碼編排不利於感性記憶和分類。
說明:數字是一個整體,每位數字的地位和含義是相同的。
反例:一個五位數字 12345,第1位是錯誤等級,第 2 位是錯誤來源,345 是編號,人的大腦不會主動地分辨每位數字的不同含義。 


下圖是《手冊》給出的錯誤碼示例:

 

 


他山之石
他山之石不一定能攻玉。
谷歌 API 錯誤碼定義
谷歌 API 的錯誤碼定義與 HTTP 狀態碼有著非常強的聯繫,並且是一個全數字錯誤碼定義。
沒有明顯的錯誤分類,快速識別和自解釋能力比較弱。

 

 


騰訊 OpenAPI(文智)錯誤碼定義
這也是一個全數字的錯誤碼,沒有明確的分類欄位,純數字的某一位已看不出明顯的分類。
不利於進行感性記憶。

 

 


微博 API 錯誤碼定義
同樣是全數字的錯誤碼定義:

 

 


其他建議
《手冊》中有一條建議:

全部正常,但不得不填充錯誤碼時返回五個零:00000。 


這也是在其他家 API 錯誤碼中能夠看到的定義。

參考
《阿裡巴巴java開發手冊》《Google API Design Guide 》(https://www.bookstack.cn/books/API-design-guide)
《阿裡雲-文件存儲-錯誤碼》(https://help.aliyun.com/document_detail/62603.html)
《微博開放平臺-API-錯誤碼》(https://open.weibo.com/wiki/Help/error)
《騰訊開放平臺-錯誤碼》(https://wiki.open.qq.com/wiki/%E9%94%99%E8%AF%AF%E7%A0%81)

 

本文來自博客園,作者:古道輕風,轉載請註明原文鏈接:https://www.cnblogs.com/88223100/p/How-to-design-the-error-code-reasonably.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1、redis哨兵(Sentinel) 1.1、redis集群介紹 前面文章講的主從複製集群是無法實現master和slave角色的自動切換的,如果master節點出現現redis服務異常、主機斷電、磁碟損壞等問題導致master無法使用,而redis主從複製無法實現自動的故障轉移(將slave 自 ...
  • 轉載自作者zhang502219048的微信公眾號【SQL資料庫編程】:Sql Server性能排查和優化懶人攻略 很多年前,筆者那時剛從廣東技術師範學院(現為廣東技術師範大學,以前為廣東民族學院)的電腦科學學院電腦科學與技術(師範)專業(廣東專插本,本科插本生,跨專業)畢業不久,還沒怎麼瞭解索 ...
  • 11月4日,華為開發者大會HDC2022在東莞松山湖拉開帷幕。HMS Core在本次大會上帶來了包括音頻編輯服務的高擬真歌聲合成技術、視頻編輯服務的智能提取精彩瞬間功能、3D Engine超大規模數字世界實時渲染技術,以及為聽障人群發聲的手語服務等HMS Core最新技術能力進展 。此外,HMS C ...
  • 好家伙,JS基礎接著學, 本篇內容為《JS高級程式設計》第四章學習筆記 1.原始值和引用值 ECMAScript變數可以包含兩種不同類型的數據:原始值和引用值。原始值(primitive value)就是最簡單的數據,引用值(reference value)則是由多個值構成的對象。 在把一個值賦給變 ...
  • 前言 這是疫情可視化最開始的文章,有需要瞭解的可前往查看:https://www.cnblogs.com/xi12/p/16690119.html。 本來說有時間就把這個項目完結了的,結果後面一直有事拖著,直到現在十一月份了才搞完。老樣子,先看成果。 瀏覽鏈接:https://xi1213.gite ...
  • call,apply,bind都是一種方法。 一,call() ①:call() 是可以 調用函數的。 1 function fn() { 2 console.log(12) 3 } 4 5 fn.call() // 12 ②:通過給call() 內部傳參,可以改變 this指向。 1 let Do ...
  • React 全家桶-React基礎 用於構建用戶界面的JavaScript庫。 facebook開源、組件化、聲明式編碼、React Native移動端開發、虛擬DOM+Diffing演算法 官網:https://react.docschina.org/ 第一章:React的基本使用 1.相關js庫 ...
  • 具體需求 在我的疫情可視化項目中有一個功能需要導出word文檔,在頁面點擊按鈕後處理數據生成word文件,然後自動下載文檔。 實現步驟 多番查詢後發現前端導出word,使用docxtemplater較為方便。具體使用步驟如下: 安裝docxtemplater:npm i docxtemplater ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...