dubbo异常捕获和处理流程

1、dubbo是一套远程rpc框架,那就存在两种角色,一是服务提供者,二是服务调用者;

服务提供者有时候需要throw异常,那这个时候客户端是否可以捕获,捕获的机制怎样;

  1. if (result.hasException() && GenericService.class != invoker.getInterface()) {  
  2.                try {  
  3.                    Throwable exception = result.getException();  
  4.   
  5.                    // 如果是checked异常,直接抛出  
  6.                    if (! (exception instanceof RuntimeException) && (exception instanceof Exception)) {  
  7.                        return result;  
  8.                    }  
  9.                    // 在方法签名上有声明,直接抛出  
  10.                    try {  
  11.                        Method method = invoker.getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes());  
  12.                        Class<?>[] exceptionClassses = method.getExceptionTypes();  
  13.                        for (Class<?> exceptionClass : exceptionClassses) {  
  14.                            if (exception.getClass().equals(exceptionClass)) {  
  15.                                return result;  
  16.                            }  
  17.                        }  
  18.                    } catch (NoSuchMethodException e) {  
  19.                        return result;  
  20.                    }  
  21.   
  22.                    // 未在方法签名上定义的异常,在服务器端打印ERROR日志  
  23.                    logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost()  
  24.                            + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName()  
  25.                            + ", exception: " + exception.getClass().getName() + ": " + exception.getMessage(), exception);  
  26.   
  27.                    // 异常类和接口类在同一jar包里,直接抛出  
  28.                    String serviceFile = ReflectUtils.getCodeBase(invoker.getInterface());  
  29.                    String exceptionFile = ReflectUtils.getCodeBase(exception.getClass());  
  30.                    if (serviceFile == null || exceptionFile == null || serviceFile.equals(exceptionFile)){  
  31.                        return result;  
  32.                    }  
  33.                    // 是JDK自带的异常,直接抛出  
  34.                    String className = exception.getClass().getName();  
  35.                    if (className.startsWith("java.") || className.startsWith("javax.")) {  
  36.                        return result;  
  37.                    }  
  38.                    // 是Dubbo本身的异常,直接抛出  
  39.                    if (exception instanceof RpcException) {  
  40.                        return result;  
  41.                    }  
  42.   
  43.                    // 否则,包装成RuntimeException抛给客户端  
  44.                    return new RpcResult(new RuntimeException(StringUtils.toString(exception)));  
  45.                } catch (Throwable e) {  
  46.                    logger.warn("Fail to ExceptionFilter when called by " + RpcContext.getContext().getRemoteHost()  
  47.                            + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName()  
  48.                            + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);  
  49.                    return result;  
  50.                }  
  51.            }  


从代码中我们可以出各个流程;先判断异常是否是可捕获异常,是则直接抛出,再判断是否同一个包下面,是则抛出,再判断是否是jdk提供异常是则抛出,如果都不是则抛出dubbo自定义rpc异常;

 看完源码以后,做出了新的设计,CommonException不变,各个接口模块(maven工程为单位)单独定义异常对象继承CommonException,每个模块抛出自己的模块异常(如用户模块抛出UicException),客户端中用CommonException统一捕获处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值