异常处理和日志输出使用小结

1、能通过预检查的异常直接处理,不用catch来处理,无法通过预检查的异常才去使用catch处理;


2、不要对大段代码进行try catch,只需要在非稳定代码地方进行try catch处理;


3、异常的捕获是为了处理他而不是抛弃它,如果不想处理可以传给外层的调用者,但是应用的最外层调用者必须处理它。通常在SpringMVC应用中,controller就已经是最外层的调用者了,异常最迟在这里就必须处理掉而不能将异常抛给前端,返回给前端的必须是一个处理之后的比较友好的提示信息,通常异常是在controller层或者Service层就处理掉;


4、捕获到异常时,通常做法是先将异常的详细信息输出到日志,然后再给前端返回一个比较友好的提示信息,这样在前端获取到异常结果时可以通过日志系统快速定位到问题所在,但是通常情况下日志会比较多,日志中定位问题比较困难,有以下两个建议:
  1)、日志记录详细尽可能详细,比如说包含出现异常所在的类名、方法名、出错时间、入参信息、业务异常代码、异常详细信息、异常唯一编码等,如果有异常堆栈建议也一起输出;
  2)、在输出日志时生成一个异常唯一编码输出到日志中,同时在返回给调用者的信息中带上这个编码,这样在前端捕获到异常结果时能根据这个异常唯一编码快速定位到日志对应地方;]


5、通常要捕获的异常的地方有:方法入口处进行参数为空和参数合法性检查,对框架或者JDK等底层代码抛出的异常(比如iBatis抛出的数据库操作异常、Spring框架抛出的异常、RPC调用抛出的异常、网络操作抛出的异常、除零、空指针、下标越界等JDK抛出的异常等等),业务操作异常(比如查询数据返回结果为空、数据业务合法性检查等等);其中业务操作异常建议根据业务情况做一个汇编,将每种异常分配一个统一的编码和描述信息定义为一个枚举值,这样方便业务异常的排查;


6、一定不要忘记对资源对象、流对象在try finally中关闭,并且还要做异常处理;JDK7及以上的建议使用try-with-resources的方式处理,代码看起来会简洁很多;

7、不能在finally中使用return,因为这会导致try中的return失效;


8、调用其他方法必须进行空指针判断(注意基本数据类型和基本数据类型对象,比如int和Integer,Integer有可能为NULL,而int不可能为NULL,还有级联调用也容易产生空指针异常,比如:obj.getA().getB().getC());


9、对于trace/debug/info级别的日志输出,必须使用条件输出或者占位符的方式,避免执行字符串拼接而浪费系统资源,但是日志最终却没有打印;
  比如:
  错误:logger.debug("process trade with id:" + id + "and symbol:" + symbol);
  正确:
    条件输出:
      if (logger.isDebugEnabled()) {
        logger.debug("process trade with id:" + id + "and symbol:" + symbol);
      }
    占位符:
      logger.debug("process trade with id: {} and symbol: {}", id, symbol);


10、谨慎的注意每条日志输出的级别设置:debug级别的日志用于协助调试用的,一般只输出到开发环境和测试环境吗,info级别的日志必须有选择的输出,其作用是用于协助查看系统运行状况;debug和info级别的日志严禁在生产环境输出;warn级别的日志用于非系统和业务错误,但是会影响系统输出结果的信息,比如记录用户输入参数错误的情况可以使用warn级别日志,避免用户投诉时有据可依;error级别只记录系统逻辑错误、异常等重要的错误信息,如非必要,请不要使用这个级别;

猜你喜欢

转载自www.cnblogs.com/laoxia/p/10875270.html