架构之全局错误异常定义

2019-12-18  本文已影响0人  rickJinzhu

异常简介

说明

一个开发框架少不了异常处理机制,让所有的错误集中在一个地方处理,在业务代码开发的时候,往外抛就可以了,由上层统一拦截处理、返回给调用方。
这里我们使用了自定义错误码,并将错误码定义在了错误码枚举类中,当然如果你的系统比较庞大,错误码非常多,并且要实现错误码的动态调整,那么也可以将错误码存在数据库中,启动后放到内存缓存,这里为了方便大家理解只是提前将错误码定义在了枚举类中。

UML图


异常定义

错误码定义

通过实现此接口扩展应用程序中的错误代码

public interface ErrorCodeI {

    public String getErrCode();

    public String getErrDesc();

}

基础错误码定义

定义3个基本错误代码

public enum BasicErrorCode implements ErrorCodeI {

    BIZ_ERROR("BIZ_ERROR" , "通用的业务逻辑错误"),

    ZCB_ERROR("ZCB_FRAMEWORK_ERROR" , "ZCB框架错误"),

    SYS_ERROR("SYS_ERROR" , "未知的系统错误" );

    private String errCode;

    private String errDesc;

    private BasicErrorCode(String errCode, String errDesc){
        this.errCode = errCode;
        this.errDesc = errDesc;
    }

    @Override
    public String getErrCode() {
        return errCode;
    }

    @Override
    public String getErrDesc() {
        return errDesc;
    }
}

基础异常信息定义

基异常是所有异常的父级,需要继承运行时异常RuntimeException

public abstract class BaseException extends RuntimeException{

    private static final long serialVersionUID = 1L;
    
    private ErrorCodeI errCode;
    
    public BaseException(String errMessage){
        super(errMessage);
    }
    
    public BaseException(String errMessage, Throwable e) {
        super(errMessage, e);
    }
    
    public ErrorCodeI getErrCode() {
        return errCode;
    }
    
    public void setErrCode(ErrorCodeI errCode) {
        this.errCode = errCode;
    }
    
}

框架异常定义

扩展框架的基础结构异常

public class ZCBException extends BaseException {
    
    private static final long serialVersionUID = 1L;
    
    public ZCBException(String errMessage){
        super(errMessage);
        this.setErrCode(BasicErrorCode.ZCB_ERROR);
    }
    
    public ZCBException(String errMessage, Throwable e) {
        super(errMessage, e);
        this.setErrCode(BasicErrorCode.ZCB_ERROR);
    }
}

通用业务异常定义

扩展框架的业务已知异常

public class BizException extends BaseException {

    private static final long serialVersionUID = 1L;

    public BizException(String errMessage){
        super(errMessage);
        this.setErrCode(BasicErrorCode.BIZ_ERROR);
    }

    public BizException(ErrorCodeI errCode, String errMessage){
        super(errMessage);
        this.setErrCode(errCode);
    }

    public BizException(String errMessage, Throwable e) {
        super(errMessage, e);
        this.setErrCode(BasicErrorCode.BIZ_ERROR);
    }
}

系统异常定义

扩展框架系统意外异常

public class SysException extends BaseException {

    private static final long serialVersionUID = 4355163994767354840L;

    public SysException(String errMessage){
        super(errMessage);
        this.setErrCode(BasicErrorCode.SYS_ERROR);
    }

    public SysException(ErrorCodeI errCode, String errMessage) {
        super(errMessage);
        this.setErrCode(errCode);
    }

    public SysException(String errMessage, Throwable e) {
        super(errMessage, e);
        this.setErrCode(BasicErrorCode.SYS_ERROR);
    }

    public SysException(String errMessage, ErrorCodeI errorCode, Throwable e) {
        super(errMessage, e);
        this.setErrCode(errorCode);
    }
}

异常处理

异常处理接口定义

ExceptionHandlerI提供了一个后门,应用程序可以覆盖默认的异常处理

public interface ExceptionHandlerI {
    public void handleException(Command cmd, Response response, Exception exception);
}

异常处理工厂

这里提供一种扩展机制,如果自己有实现异常处理机制,则执行自定义的异常处理,没有就走默认的异常处理机制。

public class ExceptionHandlerFactory {

    public static ExceptionHandlerI getExceptionHandler(){
        try {
            return ApplicationContextHelper.getBean(ExceptionHandlerI.class);
        }
        catch (NoSuchBeanDefinitionException ex){
            return DefaultExceptionHandler.singleton;
        }
    }

}

默认异常处理

默认捕获异常并打印日志,并在对应的返回信息返回错误码。

public class DefaultExceptionHandler implements ExceptionHandlerI {

    private Log logger = LogFactory.getLog(ExtensionExecutor.class);

    public static DefaultExceptionHandler singleton = new DefaultExceptionHandler();

    @Override
    public void handleException(Command cmd, Response response, Exception exception) {
        buildResponse(response, exception);
        printLog(cmd, response, exception);
    }

    private void printLog(Command cmd, Response response, Exception exception) {
        if(exception instanceof BaseException){
            //biz exception is expected, only warn it
            logger.warn(buildErrorMsg(cmd, response));
        }
        else{
            //sys exception should be monitored, and pay attention to it
            logger.error(buildErrorMsg(cmd, response), exception);
        }
    }

    private String buildErrorMsg(Command cmd, Response response) {
        return "Process [" + cmd + "] failed, errorCode: "
                + response.getErrCode() + " errorMsg:"
                + response.getErrMessage();
    }

    private void buildResponse(Response response, Exception exception) {
        if (exception instanceof BaseException) {
            ErrorCodeI errCode = ((BaseException) exception).getErrCode();
            response.setErrCode(errCode.getErrCode());
        }
        else {
            response.setErrCode(BasicErrorCode.SYS_ERROR.getErrCode());
        }
        response.setErrMessage(exception.getMessage());
        response.setSuccess(false);
    }
}

异常处理调用

在最上层框架进行调用,为异常处理的总入口。

    public Response invoke(Command command) {
        Response response = null;
        try {
            preIntercept(command);
            response = commandExecutor.execute(command);  
        }
        catch(Exception e){
            response = getResponseInstance(command);
            response.setSuccess(false);
            ExceptionHandlerFactory.getExceptionHandler().handleException(command, response, e);
        }
        finally {
            //make sure post interceptors performs even though exception happens
            postIntercept(command, response);
        }          
        return response;
    }

使用场景

系统异常

    public static<T> T getBean(Class<T> targetClz){
        T beanInstance = null;
        //优先按type查
        try {
            beanInstance = (T) applicationContext.getBean(targetClz);
        }catch (Exception e){
        }
        //按name查
        if(beanInstance == null){
            String simpleName = targetClz.getSimpleName();
            //首字母小写
            simpleName = Character.toLowerCase(simpleName.charAt(0)) + simpleName.substring(1);
            beanInstance = (T) applicationContext.getBean(simpleName);
        }
        if(beanInstance == null){
            new SysException(BasicErrorCode.SYS_ERROR, "Component " + targetClz + " can not be found in Spring Container");
        }
        return beanInstance;
    }

业务异常

 public static void notNull(Object object, ErrorCodeI errorCode, String message) {
        if (object == null) {
            throw new BizException(errorCode, message);
        }
    }

自定义异常

 private void checkNull(BizScenario bizScenario){
        if(bizScenario == null){
            throw new ZCBException("BizScenario can not be null for extension");
        }
    }

个人网站:http://www.cnzcb.cn

本文由博客一文多发平台 OpenWrite 发布!

上一篇下一篇

猜你喜欢

热点阅读