異常處理:
實現(xiàn)一個基礎(chǔ)服務(wù)或者是后端服務(wù),異常處理很重要。
如果不能給客戶端返回一個友好的異常,那么這個api設(shè)計是失敗的。會給client帶來很大的困擾。
一些例子
1.Symja 數(shù)據(jù)運(yùn)算引擎
MathException
返回:message
2.Zookeeper
KeeperException
返回:Message + ErrorCode
3.Odis rpc
RpcException
解決方案
基于現(xiàn)有開源的一些服務(wù)以及自己公司內(nèi)部的組件,結(jié)合個人的經(jīng)驗。有下面兩種備選的方案。
Solution1
不拋出異常。而是提供一個類似Status的類作為返回值,包含message和code表示錯誤信息。供客戶端使用。
Solution2
提供一個基類異常xxxException,異常信息包含message跟error code。
作為checked exception??蛻舳丝梢赃x擇根據(jù)異常類型來做相應(yīng)的處理(比如:open database的時候做retry操作等等)
當(dāng)然,不一定非得限制在一個exception,可以派生出不同類型的異常,但是不能太多。不然client使用很不方便/
注意事項
1、不能直接throw exception給上游
2、每個public api需要寫好異常說明
3、盡量不要renew 然后 throw exception,會有性能負(fù)載
4、catch到checked exception,需要打印log,方便排查問題
5、 If a client can reasonably be expected to recover from an exception, make
it a checked exception. If a client cannot do anything to recover from the
exception, make it an unchecked exception.(比如,database整個掛了, 那么client應(yīng)該不知道如何處理,個人理解)
6、持續(xù)更新
小結(jié)
我個人是比較傾向于exception的方式來處理。
1、大部分項目都是使用exception來處理異常情況的。代碼使用上面會有很好的一致性。
2、可以封裝。比如database 文件系統(tǒng)層面訪問的異常,可以在database邏輯里面封裝好成一個新的checked exception,而不是直接拋給業(yè)務(wù)層。
3、可以增加更多的public get方法,讓client能獲取更詳細(xì)的信息
4、status的話,假如有runtimeexception等unchecked exception的時候,個人覺得應(yīng)該讓上游捕獲到的,但是返回status就可能把這個信息隱藏了。
5、參考zookeeper的設(shè)計和實現(xiàn)
設(shè)計
KVException
包含:
1、message
2、code
其他類型可以繼承這個基類作封裝重載。
一定要寫好各種類型異常的說明,給client提供足夠信息來處理
Reference
Best Practices for Exception Handling
15 Best Practices For java exception handling
Effective Java-Exceptions