[编织消息框架][JAVA核心技术]异常应用

 

QException是项目业务异常基类 按模块划分子类异常,方便定位那块出错

有个来源码属性code作用定位某个功能处理出错逻辑,数字类型节省内存空间,同时减少创建子类的子类

QSocketException 是通信层出错 凡是来自QSocketException 统一认为非法请求,强制关闭socket连接

QJsonException 是json编解码出错 json很流行种数据格式,跨平台特点,经常处理

QEnhanceException 是Javassist动态生成java class技术,用于替换jdk 动态代理

 

 1 public class QException extends RuntimeException {
 2 
 3     private static final long serialVersionUID = -3110633035340065406L;
 4 
 5     private short code;
 6 
 7     public short getCode() {
 8     return code;
 9     }
10 
11     public QException(short code, String message, Throwable cause) {
12     super(message, cause);
13     this.code = code;
14     }
15 
16     public QException(short code) {
17     super();
18     this.code = code;
19     }
20 
21     public QException(short code, String message) {
22     super(message);
23     this.code = code;
24     }
25 
26 }
QException

 

接下来应用异常

首先要找到所有业务调用的主入口,由于用的是netty通信框架,对于服务端来讲要找到接收数据的方法

ChannelDuplexHandler 是netty提供的业务实现的类,其中channelRead是接收数据的方法

 1 @Sharable
 2 public class QMessageHandler extends ChannelDuplexHandler {
 3 
 4     private QDispenseHandler dispenseHandler;
 5 
 6     public QMessageHandler(QDispenseHandler dispenseHandler) {
 7         this.dispenseHandler = dispenseHandler;
 8     }
 9 
10     @Override
11     public void channelActive(ChannelHandlerContext ctx) throws Exception {
12         dispenseHandler.doConnect(ctx);
13         super.channelActive(ctx);
14     }
15 
16     @Override
17     public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
18         dispenseHandler.doReceive(msg, ctx);
19         super.channelRead(ctx, msg);
20     }
21 
22     @Override
23     public void channelInactive(ChannelHandlerContext ctx) throws Exception {
24         dispenseHandler.doClose(ctx);
25         super.channelInactive(ctx);
26     }
27 }

 

QDispenseHandler.class 

当业务处理失败时,响应三种策略

1.优先处理来自QSocketException强制关闭socket连接

2.业务边界QException

3.未知错误Exception

第一种情况不用返回响应码

第二三种情况是否返回根据客户端请求状态决定 boolean response = packet.hasStatus(QPacket.MASK_RESPONSE)

 1  public void doReceive(Object msg, ChannelHandlerContext ctx) {
 2     if (msg instanceof QPacket) {
 3         pool.execute(() -> {
 4         doReceive0((QPacket) msg, ctx);
 5         });
 6     }
 7  }
 8 
 9  private void doReceive0(QPacket packet, ChannelHandlerContext ctx) {
10 
11     boolean response = packet.hasStatus(QPacket.MASK_RESPONSE);
12     try {
13         //doReceive ... 处理省略细节
14         
15     } catch (QSocketException e) {
16         // socket异常 关闭连接
17         packet.responseCode(e.getCode());
18         LOGGER.error("QSocketException  msg {} error : {}", QCodeUtil.getDes( e.getCode()), e);
19         if (response) {
20         ChannelFuture future = ctx.channel().writeAndFlush(packet);
21         future.addListener(new GenericFutureListener<Future<? super Void>>() {
22             @Override
23             public void operationComplete(Future<? super Void> future) throws Exception {
24             NettyUtil.closeChannel(CLOSE_SOURCE.SOCKET_ERROR, false, ctx.channel());
25             }
26         });
27         } else {
28         NettyUtil.closeChannel(CLOSE_SOURCE.SOCKET_ERROR, false, ctx.channel());
29         }
30         return;
31     } catch (QException e) {
32         // 业务异常 响应失败
33         packet.responseCode(e.getCode());
34         LOGGER.error("QException  msg {} error : {}",QCodeUtil.getDes( e.getCode()), e);
35     } catch (Exception e) {
36         // 未知异常 响应失败
37         packet.responseCode(QCode.ERROR_UNKNOWN);
38         LOGGER.error("UNKNOWNException  error : {}", e);
39     }
40     if (response) {
41         ctx.channel().writeAndFlush(packet);
42     }
43  }

 

posted @ 2017-03-23 14:58  solq321  阅读(303)  评论(2编辑  收藏  举报