最近开发的项目中,dao,service,controller中的类都是throws Excepiton,但在方法中为什么还要catch后再抛,想知道SSM开发web应用详细的异常处理机制
认证高级PHP讲师
以下仅为个人做法,仅供参考。
Controller层:在没有AOP或Filter介入的情况下,个人认为这里的所有方法内产生的异常都要处理;
Controller
AOP
Filter
DAO层:这一层的异常多为SQL异常,一般抛给Service层处理;
DAO
Service
Service层:如果认为该异常无需调用者介入处理,则在Service内部处理,反之则抛给调用者处理(其实就是甩锅……);
只有一种情况下,我才会catch之后再throw一个Exception,就是catch了A异常,然后抛出了B异常,这通常跟使用AOP统一处理异常搭配,例如:catch了A,B,C异常,统一交给AOP的D异常处理器处理。
Exception
个人认为catch异常的原则是当代码对期待的异常有业务处理需要的时候才需要catch异常,比如SQL错误的时候需要回滚事务之类的,其它基本没必要catch异常,让最外层业务进行统一处理异常即可。
几个个人建议:
(1)检查型异常转为RuntimeException,抛这个一般认为是bug(2)自定义异常(业务异常)继承自RuntimeException,设计自定义异常的时候要考虑异常抛出的时候能够通过日志信息快速重现发生异常的场景。(3)关于是否抛出异常,一般来说如果需要调用方知晓可能会发生业务异常,并能处理的,就抛。如果调用方无法处理的异常,就catch掉。简而言之就是不要“甩锅”。(4)强烈不建议catch Exception,这种代码在发生异常的时候很难快速定位问题。
RuntimeException
catch Exception
建议Dao层,直接往上抛异常(一般都是数据库的运行时异常),Service层因为是暴露给其它应用的,并且会有很多业务信息需要传递给上层的调用者,所以这里有两种方式
Dao
通过抛出业务异常来,告知调用方具体的业务异常信息/系统异常信息(系统异常,上层可能不会关注)
Service中保证不会出现异常,并且返回一个Result给上层,Result里面包括的信息有:这次调用是否成功,如果失败会有一些业务信息
Result
所以不用层层都去抓异常,如果要处理就在Service中处理(不管是单应用还是以后的服务化),具体在service中是以上述的哪种方式,具体看团队的选择了
大体的业务流程我们是用try{}catch{}来控制,还是用if()来控制
以下仅为个人做法,仅供参考。
Controller
层:在没有
AOP
或Filter
介入的情况下,个人认为这里的所有方法内产生的异常都要处理;DAO
层:这一层的异常多为SQL异常,一般抛给
Service
层处理;Service
层:如果认为该异常无需调用者介入处理,则在Service内部处理,反之则抛给调用者处理(其实就是甩锅……);
只有一种情况下,我才会catch之后再throw一个
Exception
,就是catch了A异常,然后抛出了B异常,这通常跟使用AOP
统一处理异常搭配,例如:catch了A,B,C异常,统一交给AOP
的D异常处理器处理。个人认为catch异常的原则是当代码对期待的异常有业务处理需要的时候才需要catch异常,比如SQL错误的时候需要回滚事务之类的,其它基本没必要catch异常,让最外层业务进行统一处理异常即可。
几个个人建议:
(1)检查型异常转为
RuntimeException
,抛这个一般认为是bug(2)自定义异常(业务异常)继承自
RuntimeException
,设计自定义异常的时候要考虑异常抛出的时候能够通过日志信息快速重现发生异常的场景。(3)关于是否抛出异常,一般来说如果需要调用方知晓可能会发生业务异常,并能处理的,就抛。如果调用方无法处理的异常,就catch掉。简而言之就是不要“甩锅”。
(4)强烈不建议
catch Exception
,这种代码在发生异常的时候很难快速定位问题。建议
Dao
层,直接往上抛异常(一般都是数据库的运行时异常),Service
层因为是暴露给其它应用的,并且会有很多业务信息需要传递给上层的调用者,所以这里有两种方式通过抛出业务异常来,告知调用方具体的业务异常信息/系统异常信息(系统异常,上层可能不会关注)
Service
中保证不会出现异常,并且返回一个Result
给上层,Result
里面包括的信息有:这次调用是否成功,如果失败会有一些业务信息所以不用层层都去抓异常,如果要处理就在
Service
中处理(不管是单应用还是以后的服务化),具体在service中是以上述的哪种方式,具体看团队的选择了大体的业务流程我们是用try{}catch{}来控制,还是用if()来控制