dubbo处理自定义异常问题
来源:互联网 发布:网络加盟代理 编辑:程序博客网 时间:2024/05/29 07:05
最近在项目上遇到一个有关dubbo的问题,项目分为两层:下层是一些基础服务,上层是业务服务调用下层的基础服务。上层服务的有一个全局的异常拦截器来拦截异常。
@ControllerAdvice@Slf4jpublic class ExceptionFilter { @ExceptionHandler public ResponseEntity defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception { if(e instanceof MyException){ //自定义处理 } log.error(e.getMessage(), e); Result res = new Result(500, "SYSTEM_EXCEPTIONS", "系统异常"); return ResponseEntity.ok(res); }}
全局异常可以catch程序上层的异常,进行不同的处理,进行更加友好的提示。
下层抛出的异常:
public void text(){ throw new MyException("aaaa");}
然后遇到了一个奇怪的问题,在下层中抛出了一个自定义的异常,但是在上层中捕获异常的时候,却是捕获到runtimeException异常,异常中的message存放了我们需要的对象异常。导致就无法对自定义的异常做特殊处理。
java.lang.RuntimeException: MyException: aaa
查阅了一下资料以后是因为dubbo对异常进行了处理,如果Dubbo的暴露抛出异常(Throwable),则会被暴露方的ExceptionFilter拦截到,执行以下invoke方法:
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; } }
从代码可以看出,duubo只会抛出受检
异常、jdk自身的异常、方法上申明的异常、dubbo自带的RpcException异常等等,其他的都会包装成new RuntimeException(StringUtils.toString(exception))抛出,所以也有了我遇到的问题。
只要的发生问题的原因就可以解决问题:
- 可以在暴露方法的时候声明异常
- 可以把异常设置为受检异常
- 可以把异常和api包放在同一个jar包中
- provider实现GenericService接口
- 自定义异常继承dubbo的异常类
上述方法是在ExceptionFilter的基础上,可以换个思路,通过订制错误码,把遗产放在对象中进行处理,不过这个思路对使用方的改动较大,需要在开始定义架构的时候的时候进行约定。也可以使用修改配置文件跳过ExceptionFilter这个拦截器,但是这样做暴露方会把所有的原始异常暴露给使用者。
跳过异常拦截器的配置
<dubbo:provider ....... ... filter="-exception"/>
阅读全文
0 0
- dubbo处理自定义异常问题
- 自定义异常处理问题
- Dubbo生产者抛出自定义异常的问题
- Dubbo生产者抛出自定义异常的问题
- Dubbo生产者抛出自定义异常的问题
- Dubbo抛出自定义异常
- Dubbo抛出自定义异常
- dubbo(四)异常处理
- Dubbo分布式项目自定义异常前端捕获问题
- dubbo实践1..异常处理
- 异常处理+异常+处理异常+自定义异常
- 使用dubbo自定义返回对象异常
- dubbo捕获提供者抛出的自定义异常
- 系统解耦问题-不同系统间dubbo调用的异常处理-ExceptionFilter
- Java异常处理-----自定义异常
- Java异常处理--自定义异常
- 浅谈dubbo的ExceptionFilter异常处理
- 使用Dubbo框架,异常处理原则
- Linux cd命令
- Tensorflow一些常用基本概念与函数
- Android实现购物车逻辑
- 0—999的水仙花数
- hiho 1638 小Hi的天平 [Offer收割]编程练习赛36 Problem B 并查集+图dfs乱搞
- dubbo处理自定义异常问题
- 多态
- linux 代码实现文件夹及其文件的
- 郝斌老师C语言学习笔记----基本类型指针
- SpringBoot--整合RabbitMq
- [bzoj2761][暴力]不重复数字
- jquery实现选项卡
- 数据结构-数据类型
- mac版MySQL初始密码修改