异常处理机制-从零开始到自定义

什么是异常处理机制

    异常处理机制是处理系统非正常运行的流程
    系统在运行时候,会出现因子系统实现错误、外界非法输入、环境引发硬件故障等因素造成的偏离正常执行流程的情况。异常处理机制考虑的就是当这些异常情况出现的时候,如何处理能够使能损失降到最低。

异常处理机制构成

    1 异常检测
    2 异常抛出;
    3 异常捕获;
    4 异常处理。
    用伪代码示例把他们结合起来就是

// try代码块开始的地方就是异常捕获的开始位置
// try代码块结束的地方就是异常捕获的结束位置
try{
  if(检测到异常){
    throw  new Exception("异常信息")
  }
}catch(Exception e){
    if(需要处理异常){
       处理异常
   }else{
       // 不处理,并且抛给try开始的这段代码被调用的方法处理
       throw e
  }
}

虽然简单,但是所有异常处理机制莫不如此构建。

异常处理原则

    1 内部能处理的自己处理;
    2 内部处理不了的丢给调用者;
    3 每层系统都设置全局异常处理者。

try-catch异常捕获的局限

     1 不能跨线程捕获异常;
     每个包含try catch的方法都有一个Exception tab,Exception tab里面每一条exception 定义了一个Exception的可能发生起始位置,Exception类型,如果匹配成功去哪一行开始执行。当抛出异常后,虚拟机便从当前方法的异常表进行异常匹配,如果匹配成功则进行异常处理,如果匹配不成功则去该方法的调用地方(也是一个方法)去匹配异常表,如何找到该方法的调用方法呢,其实就是利用了线程的方法栈,先调用的方法先入栈,后调用的后入栈,以此类推直到线程的方法栈为空为止。由于每个线程是有唯一的栈,所以当处于不同线程时候,被调用方法进行异常匹配时候便找不到调用它的方法,所以不能跨线程捕获异常, java、 c++、 js都是如此。
     2 不能跨语言捕获异常
     不同的语言采用的方法栈不是一个栈,比如Android中有java栈-虚拟机栈,C栈-本地方法栈,当在java层用try catch捕获异常,如果在try代码块中调用的native方法出现了异常,java层是无感知的,需要额外在c++层进行捕获,这也是每层系统都需要自己的全局异常处理的原因之一。

对异常处理机制的期待

     1 对未捕获的异常有自己处理方式
     2 支持线上用户异常的感知与分析
     3 对整个系统来说有统一的异常处理机制
     4 异常可以跟用户行为日志关联起来,方便定位问题

如何自定义异常处理机制

1 找到替换本层系统全局异常处理器的方案;
2 自定义异常处理方法处理已知异常;
3 添加定位异常需要的额外信息,比如用户id,重新组合后再抛给APM平台。
4 通过用户id,可以在用户行为日志上传系统上查找对应的用户行为日志和相关信息,
如果日志系统没有该用户行为日志,可以通过用户id在push系统中,直接给对应用户发一条指令,自动上传手机本地日志信息。
Demo:https://github.com/kingkong-li/AwesomeProject

小结

    一个好的异常处理机制就是当异常出现的时候,能将损失降到尽可能低,并能以尽量低的成本去定位线上问题

你可能感兴趣的:(异常处理机制-从零开始到自定义)