您好,登錄后才能下訂單哦!
本篇文章為大家展示了dotNET中怎樣處理程序中的異常,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。
平時(shí)在軟件開發(fā)的過程中,首先是要保證功能可以正常運(yùn)行,滿足業(yè)務(wù)需求,除此之外,還需要考慮代碼在異常的時(shí)候怎么處理,讓程序能夠健壯地運(yùn)行。正確合理地處理異??梢詼p少程序的 Bug、保證代碼質(zhì)量,當(dāng)然也不是一件很容易的事。
在日常工作中我們排查錯(cuò)誤時(shí)經(jīng)常會(huì)遇到這樣一些問題,如果沒有,說明你做的還不錯(cuò)了:
想通過日志的方式分析錯(cuò)誤原因,發(fā)現(xiàn)日志記錄不完整;
找到錯(cuò)誤日志了,記錄的是“未將對(duì)象引用設(shè)置到對(duì)象的實(shí)例”,也知道代碼行數(shù),然而這一行上有多個(gè)引用類型的對(duì)象,還是不知道真實(shí)原因;
問題是偶發(fā)的,無法重現(xiàn)。
最終需要還原數(shù)據(jù)庫(kù)進(jìn)行單步調(diào)試才能解決問題,然而:
客戶的數(shù)據(jù)庫(kù)涉密,不能提供;
客戶的數(shù)據(jù)庫(kù)運(yùn)行多年,數(shù)據(jù)量很大,無法快速備份還原;
如果是互聯(lián)網(wǎng) Saas 應(yīng)用,更是難于將庫(kù)拿到本地進(jìn)行調(diào)試。
所以需要在代碼層面、在日志層面來進(jìn)行優(yōu)化來達(dá)到可以快速定位問題的目的。
上面這張圖,經(jīng)歷過 dotNET Framework 時(shí)代的程序員應(yīng)該都不陌生,這就是經(jīng)典的「黃頁」和經(jīng)典的 「未將對(duì)象引用設(shè)置到對(duì)象的實(shí)例」錯(cuò)誤。
首先這個(gè)錯(cuò)誤顯示非常不友好,除了讓人知道這個(gè)是 dotNET 開發(fā)的,別無他用,另外這個(gè)錯(cuò)誤提示對(duì)排查錯(cuò)誤也沒有幫助,只知道對(duì)象為 null 了,但原因是什么并不知道,只能猜,能不能猜中就得看運(yùn)氣了。
一個(gè)系統(tǒng)一般有兩類人使用,普通用戶和系統(tǒng)管理員。不管是普通用戶還是系統(tǒng)管理員,在操作系統(tǒng)時(shí)都期望所有的操作是有反饋的,要么正常返回想要的結(jié)果,要么給出友好的錯(cuò)誤提示,能夠指引進(jìn)行下一步操作。
當(dāng)出現(xiàn)異常時(shí),可以導(dǎo)向一個(gè)專屬類型的錯(cuò)誤提示頁面,也可以以模態(tài)的方式彈出錯(cuò)誤提示,內(nèi)容包含:
錯(cuò)誤提示,例如:系統(tǒng)異常,請(qǐng)聯(lián)系管理員,撥打 xxx 、保存失敗,請(qǐng)聯(lián)系管理員;
全局錯(cuò)誤碼,下面會(huì)講到;
異常編碼,可以根據(jù)此編碼在后臺(tái)的日志記錄快速查詢,異常編碼使用日期加流水號(hào)即可,建議不要使用 Guid,曾經(jīng)被非技術(shù)人員當(dāng)成是亂碼。
如果是系統(tǒng)管理員使用的功能,將真實(shí)錯(cuò)誤原因顯示在錯(cuò)誤提示中,我認(rèn)為也是可以的。
設(shè)置全局錯(cuò)誤碼,可以讓管理員在收到反饋的錯(cuò)誤時(shí)能快速地根據(jù)錯(cuò)誤碼進(jìn)行問題的定位和找到解決方法。所以需要有公開的全局錯(cuò)誤碼文檔,記錄錯(cuò)誤的原因和解決方案參考。
大類上可以分為 4xx 和 5xx,4xx 表示前端的參數(shù)問題、驗(yàn)證問題等,5xx 表示后端的邏輯問題。
在 5xx 類型中可以再進(jìn)行細(xì)分,例如:
500100:表示數(shù)據(jù)庫(kù)操作相關(guān)問題
500200:表示列表展示相關(guān)問題
等等
1、在方法中不要返回錯(cuò)誤碼,因?yàn)殄e(cuò)誤碼的信息太單一;
2、拋異常時(shí)選擇具體的異常類型,不要直接拋出 System.Exception ;
3、錯(cuò)誤信息目的是為了讓開發(fā)人員可以定位問題和解決問題,而不是給最終用戶看,給前端用戶看的信息要友好易懂;
4、不能吞異常,比如 catch 異常后不做任何處理,如果有些資源需要清理,可以使用 try…finally 或者使用 using ;
5、只有當(dāng)你知道怎么樣從異常中恢復(fù)時(shí),才需要去捕獲異常,在執(zhí)行一些操作時(shí),我們可能知道出現(xiàn)錯(cuò)誤的原因,但無法恢復(fù),這時(shí)不要去捕獲異常。
一個(gè)方法中有三個(gè)部分:參數(shù)、業(yè)務(wù)邏輯和返回值
引用類型的參數(shù),在方法的開始一定要做非空判斷,判斷后是拋異常還是繼續(xù)下面的邏輯這個(gè)要根據(jù)具體情況來定:
如果參數(shù)為 null 時(shí)會(huì)對(duì)后續(xù)的業(yè)務(wù)有影響,就應(yīng)該拋出異常;
如果我們判斷 null 后能做一些初始化處理,能讓程序繼續(xù)正常運(yùn)行,而且保證業(yè)務(wù)也是正確的,就不必拋異常。
業(yè)務(wù)邏輯的部分分為三種情況:
在方法內(nèi)部調(diào)用其他類型的一個(gè)方法,比如 var user= userService.GetUser();
對(duì) user 的判斷,當(dāng)為 null 時(shí)是否拋異常,跟上面參數(shù)的邏輯一致;
多個(gè)邏輯組合到一起進(jìn)行判斷后,如果不能滿足下一步的輸入,應(yīng)該拋出異常;
對(duì)于更低一層的調(diào)用,有時(shí)會(huì)進(jìn)行異常的捕獲,當(dāng)捕獲到異常后,應(yīng)該要拋出符合當(dāng)前上下文的專有異常信息,更利于定位問題。
一個(gè)方法的返回值可以返回值類型,如 string、int、bool ,也可以返回引用類型,如返回一個(gè) User 對(duì)象,不管是返回什么類型,原則是一樣的,都需要更具上下文來進(jìn)行判斷。
有個(gè) GetUser 方法來獲取用戶對(duì)象 ,如果根據(jù) Id 沒有找到用戶,可以直接返回 null ,而不是返回一個(gè)空的 User 對(duì)象,如果返回空對(duì)象,程序不會(huì)出錯(cuò),但前端展示卻沒有數(shù)據(jù),就搞不清是沒找到用戶,還是找到了但沒值;返回 null,可以由上層來決定怎么來處理。
再有個(gè) GetUserList 方法根據(jù)條件獲取用戶集合,如果根據(jù)搜索條件沒有找到符合的用戶,可以返回空對(duì)象 List
對(duì)于值類型也是一樣,要看上下文,比如 C# 中用來查找字符在一個(gè)字符串中的索引位置的函數(shù) IndexOf ,返回的是 int 類型,當(dāng)找不到的時(shí)候返回的是 -1 ,而不是 null 。
上述內(nèi)容就是dotNET中怎樣處理程序中的異常,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。