上一章,咱們一塊兒學習了打日誌的點點滴滴,不少同窗跟我反饋,本身好像歷來沒打對過日誌,也有同窗跟我吐槽,MD,最討厭那些吞異常的SX。程序員
今天,咱們就來看看這個有意思的問題: 異常到底該怎麼拋?spring
今天,我依然在地鐵上與你分享,加班🐶,傷不起。﹏。數據庫
講解異常以前,咱們先看另一個問題: http的狀態碼有哪些?服務器
這個我相信你們都很熟悉了,我隨便說幾個:框架
200,成功學習
400,錯誤的請求測試
401,未認證指針
403,未受權日誌
500,服務器內部錯誤blog
503,網關錯誤
嗯,知道這麼幾個就差很少了,其中,401和403,一個表示未認證,一個表示未受權,未認證能夠理解爲沒有登陸的意思,未受權能夠理解爲沒有權限,有多是沒登陸沒有權限,也有多是登陸可是你就是沒有權限,這不是本文的重點,仔細體會一下就好。
咱們主要來看400和500這兩個狀態碼,400表示錯誤的請求,500表示內部服務器錯誤,他們有什麼本質的區別麼?
用一句話來解釋,一個表示由於客戶端的參數不對致使服務器沒法繼續處理引發的錯誤,一個表示服務器內部的某些因素致使的錯誤,這裏的某些因素多是代碼問題,數據庫問題,遠程調用問題,等等。
對於400錯誤,咱們通常本身檢查下請求參數就能夠給用戶友好的提示,好比,新增用戶卻沒有填寫用戶名,咱們直接提示用戶名不能爲空就行了。
對於500錯誤,它是服務器內部的錯誤,好比你的代碼空指針了,數據庫用戶名這個字段長度不夠,A調B,B卻不通,等等,這種異常你怎麼給用戶提示呢?無法提示,不能直接把異常堆棧給用戶吧(有沒有中招😁)
好吧,這下真的用一句話來總結,400是用戶的錯誤,500是程序員的錯誤,啊哈哈。
針對這兩種錯誤呢,咱們使用spring框架通常都會作統一的異常處理層。
好比說,個人新項目,我分別定義了兩個異常類,BadRequestException和SeverErrorException,而後在spring異常層判斷若是是BadRequestException我就直接返回msg,若是是SeverErrorException我就所有返回"內部服務器錯誤"。
本覺得,你們都按我這個來用就行了,結果,轉測以後,測試每天在羣裏喊,咋回事啊,怎麼全都是"內部服務器錯誤",快點幫我查一下。
我,握了棵草,查看了幾我的的代碼以後,我發現,所有在亂用,被逼無奈之下,我讓他們都改一下,而後每一個人都問我一下,爲何不能用這個卻要用那個,前面幾個我還能耐心的給講講細節,後面我實在不耐煩了,最後,亮出了個人大招。
我在common中把ServerErrorException移到了與異常處理類同包下,並把其可見性改爲了包包內可見,而後,對全部人說大家只能使用BadRequestException,ServerErrorException只能我在框架層使用,算是完全解決了這個問題。
寫了這麼多,好像尚未講到今天的主題: 異常怎麼拋的問題。
其實,對於業務開發者,真正能使用到的就應該是隻有對於客戶端錯誤的檢查本身手動拋出異常,其餘的異常一概不須要關心,好比空指針異常,遠程調用異常,數據庫異常,你要相信,這些異常都會在框架層處理的很好。
不須要在你的代碼起止加try catch!
不須要在你的代碼起止加try catch!
不須要在你的代碼起止加try catch!
固然,受檢異常除外,什麼是受檢異常的,簡單點講,就是非運行時異常,好比,讀取文件,有可能拋出FileNotExistException,這類異常須要你手動捕獲異常,在編譯期就須要try catch,可是,即便這樣,你也應該保證你的try catch範圍足夠小,只包住那一個方法調用便可,而且,在catch中包裝成你本身的運行時異常繼續往外拋。
咦,這裏就可能會出現開頭說的吞異常的問題了,因此說try catch必定要按下面的格式寫:
try {
} catch (XxxException e) {
throw new YourRuntimeException("xxx文件不存在",e);
}
注意,這裏不須要打印日誌,直接帶上e往外拋就行了。
若是不帶e,就變成吞異常了。
最後,爲何500不能隨便拋呢?
正常來講,不少大公司都會監控http返回碼,若是是500是要告警的,發郵件發短信,半夜把程序員(你)叫起來去改問題的,有可能還會通報批評,很嚴重的!
好了,今天就先到這裏,大家公司是怎麼定義異常,怎麼規範拋異常的呢?歡迎留言討論。