什么时候应该抛异常?
前言
说到异常,之前一直不是太理解它的作用,项目中有用到基本都是数据库事务上。
比如:添加一个新数据,修改一条旧数据,有异常,回滚事务,没有则提交事务。这几天在给公司的支付项目开发 SDK ,又重新查一下资料,有一番新的认识,顺便记录下来。
什么时候应该抛出异常?
按照面向对象的单一职责原则,一个类只应该关心自己的逻辑,当出现问题的时候,如果不是当前类该处理的,我们就应该抛出而不是消化。怎么理解呢?比如,请求一个根据用户 id
获取用户信息接口的时候,网络出现问题,HTTP
请求库抛出了异常,这时候应该抛出异常。可是为啥不是 catch
异常然后返回 false
呢?这就涉及到边界问题了,业务异常与运行时异常要区分开,对方接口返回你要查询的 id
不存在,返回错误,这属于业务异常,这时候是不会抛出异常的。而你请求的 API
不存在,或者对方服务器宕机,或者你的服务器网络出问题,这属于运行时异常,就应该以异常抛出来告知调用方,而不是自主处理该异常并返回 false
来结束逻辑。
可能刚开始你是不太好理解,其实说白了就是边界问题。当你有更多的应用设计与代码实践经验后你会慢慢感受到这个边界。
异常的分类和命名
由于异常情况有很多,所以我们自定义异常类时通常需要做分类,方便排查原因,这是最佳实践,可以看看开源的框架、类库的源码,基本都是把异常做了分类。至于命名,先看 PHP
内置异常类是如何命名的。
- BadFunctionCallException
- BadMethodCallException
- DomainException
- InvalidArgumentException
- LengthException
- LogicException
- OutOfBoundsException
- OutOfRangeException
- OverflowException
- RangeException
- RuntimeException
- UnderflowException
- UnexpectedValueException
自定义异常类我们直接参考 PHP
内置异常类命名就好,按名称来命名:
- 参数错误,当传入的参数不合法时,我们通常抛出异常;
- HTTP 异常,在请求 API 时异常终止时抛出的异常;
- 其它异常,模块其它部分异常。
当然还有其它的,你可以命名非常细,比如 HttpException
、ErrorResponseException
等等,只要做到命名规范、清晰易懂即可。
自定义的异常需要继承 PHP
内置的异常类 Exception
,可以不包含任何方法。
您将是第一位评论人!