上一章,咱们一块儿学习了打日志的点点滴滴,不少同窗跟我反馈,本身好像历来没打对过日志,也有同窗跟我吐槽,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是要告警的,发邮件发短信,半夜把程序员(你)叫起来去改问题的,有可能还会通报批评,很严重的!
好了,今天就先到这里,大家公司是怎么定义异常,怎么规范抛异常的呢?欢迎留言讨论。