异常是分层次级别的,方法1,2,3代表异常层级。假如是方法3调用方法2,方法2调用方法1。


异常分类和层次结构

 当方法1出现异常时,首先方法1会捕获异常try catch,接着方法1的代码会决定怎么处理异常(记录日志,或者修复异常假装没发生,或者返回客户端错误)

假如不想处理异常,可以抛出去给方法2,方法2继续往上抛,也可以处理不处理,也可以往上抛。

如果能够在服务器内部正确处理异常,并且把异常纠正过来之后返回客户端正确相应结果当然是好的,但是绝大多数情况下,流程就是不正确的了,没有办法返回正常的相应结果。这时候就需要返回一个异常信息告诉服务端,我哪里出错了。

1:假如我在方法1捕获异常,我处理了,但是按照理论,我要逐一往上抛错。每一个方法要去捕获处理下面的方法抛的异常。这样代码是很繁琐的,而且我们经常遗漏捕获的异常。

2:有些异常我们是不能提前预知,或者由于经验缺失我们没有预料到这种类型异常错误。我们不会trycatch捕获,但是又是侯不trycatch 会造成程序崩溃,这样不好的。不捕获就会一直存在。没有捕获就不去处理,不去处理就一直存在。

对于这2个情况我们需要全局异常处理。对于我们API2件事情必须要做1.记录日志2.要有统一错误返回格式(错误码和错误信息),就在全局异常处理做。如果全局都不去处理,就会返回500状态码。(尽量不要有500)

全局异常处理就是我们说的AOP(切面编程思维)通常我们使用框架比如说tp5就已经有全局异常处理类,所以有时候我们想控制返回到客户端的这样的错误信息格式,哪门我们就要重写错误异常类。

异常分类和层次结构

我们把异常分为两大类

1:由于用户的行为导致的,如没查询到结果(通常应该返回空数据,而不应该视为异常,但是在rest服务里对异常的定义并不是报错,而是没有返回你所期望的结果都可以视为异常)通常不需要记录日志,但是需要返回用户具体信息。比如用户随便输入通不过你都记录,这日记体积太大了。我们要选择性记录日志。

2:服务器自身异常:代码错误(1/0),调用外部接口错误。一定要记录日志排查错误,不需要返回原因。用户不需要知道。

但是也不一定要完全按照要灵活,比如有个固定IP频繁抓取接口相关内容,此时需要日志记录观察一段时间。具体需要根据业务具体处理。异常就是不符合常规行为的都是异常。

如何区分:我们可以从结果反推,第一种异常有个硬性条件,需要向用户返回信息,我们需要定义一个类凡是属于BaseException都是属于第一种异常分类。我们只需要判断由框架传来的Exception是不是BaseException从而就可以对这样两种异常分类做一个类型区分。从正向理解,我们定义了BaseException类来代表我们的第一个分类。


相关文章: