异常处理:
实现一个基础服务或者是后端服务,异常处理很重要。
如果不能给客户端返回一个友好的异常,那么这个api设计是失败的。会给client带来很大的困扰。
一些例子
1.Symja 数据运算引擎
MathException
返回:message
2.Zookeeper
KeeperException
返回:Message + ErrorCode
3.Odis rpc
RpcException
解决方案
基于现有开源的一些服务以及自己公司内部的组件,结合个人的经验。有下面两种备选的方案。
Solution1
不抛出异常。而是提供一个类似Status的类作为返回值,包含message和code表示错误信息。供客户端使用。
Solution2
提供一个基类异常xxxException,异常信息包含message跟error code。
作为checked exception。客户端可以选择根据异常类型来做相应的处理(比如:open database的时候做retry操作等等)
当然,不一定非得限制在一个exception,可以派生出不同类型的异常,但是不能太多。不然client使用很不方便/
注意事项
1、不能直接throw exception给上游
2、每个public api需要写好异常说明
3、尽量不要renew 然后 throw exception,会有性能负载
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应该不知道如何处理,个人理解)
6、持续更新
小结
我个人是比较倾向于exception的方式来处理。
1、大部分项目都是使用exception来处理异常情况的。代码使用上面会有很好的一致性。
2、可以封装。比如database 文件系统层面访问的异常,可以在database逻辑里面封装好成一个新的checked exception,而不是直接抛给业务层。
3、可以增加更多的public get方法,让client能获取更详细的信息
4、status的话,假如有runtimeexception等unchecked exception的时候,个人觉得应该让上游捕获到的,但是返回status就可能把这个信息隐藏了。
5、参考zookeeper的设计和实现
设计
KVException
包含:
1、message
2、code
其他类型可以继承这个基类作封装重载。
一定要写好各种类型异常的说明,给client提供足够信息来处理
Reference
Best Practices for Exception Handling
15 Best Practices For java exception handling
Effective Java-Exceptions