您的位置:首页 > 其它

Dubbo生产者抛出自定义异常的问题

2017-07-27 14:40 218 查看
在使用dubbo的过程中,在dubbo的service端定义有自定义异常进行throw的时候,却发现在customer的Controller中无法instanceof,自己自定义的异常类被转成了Runtime异常,有点不理解。在翻看dubbo源码的时候,发现确实如此:

public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {

        try {

            Result result = invoker.invoke(invocation);

            if (result.hasException() && GenericService.class != invoker.getInterface()) {

                try {

                    Throwable exception = result.getException();

                    // 如果是checked异常,直接抛出

                    if (! (exception instanceof RuntimeException) && (exception instanceof Exception)) {

                        return result;

                    }

                    // 在方法签名上有声明,直接抛出

                    try {

                        Method method = invoker.getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes());

                        Class<?>[] exceptionClassses = method.getExceptionTypes();

                        for (Class<?> exceptionClass : exceptionClassses) {

                            if (exception.getClass().equals(exceptionClass)) {

                                return result;

                            }

                        }

                    } catch (NoSuchMethodException e) {

                        return result;

                    }

                    // 未在方法签名上定义的异常,在服务器端打印ERROR日志

                    logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost()

                            + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName()

                            + ", exception: " + exception.getClass().getName() + ": " + exception.getMessage(), exception);

                    // 异常类和接口类在同一jar包里,直接抛出

                    String serviceFile = ReflectUtils.getCodeBase(invoker.getInterface());

                    String exceptionFile = ReflectUtils.getCodeBase(exception.getClass());

                    if (serviceFile == null || exceptionFile == null || serviceFile.equals(exceptionFile)){

                        return result;

                    }

                    // 是JDK自带的异常,直接抛出

                    String className = exception.getClass().getName();

                    if (className.startsWith("java.") || className.startsWith("javax.")) {

                        return result;

                    }

                    // 是Dubbo本身的异常,直接抛出

                    if (exception instanceof RpcException) {

                        return result;

                    }

                    // 否则,包装成RuntimeException抛给客户端

                    return new RpcResult(new RuntimeException(StringUtils.toString(exception)));

                } catch (Throwable e) {

                    logger.warn("Fail to ExceptionFilter when called by " + RpcContext.getContext().getRemoteHost()

                            + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName()

                            + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);

                    return result;

                }

            }

            return result;

        } catch (RuntimeException e) {

            logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost()

                    + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName()

                    + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);

            throw e;

        }

    }

      // 否则,包装成RuntimeException抛给客户端

       return new RpcResult(new RuntimeException(StringUtils.toString(exception)));

最后这一段是是把我们的自定义异常给重新封装了一下了,所以我们就捕获不到自定义异常了。

导致他走这一步的原因是因为:生产者把方法接口给消费者调用的时候,没有在接口类里面对该方法进行声明异常,



导致在上面的源码中的判断有问题。



method.getExceptionTypes() =[], 没有将异常return出来,走到最后被包装成RuntimeException抛给客户端。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: