dubbo自定义异常传递信息丢失问题解决
目前计划对已有的单体项目进行组织架构拆分,调研了分布式系统中常用中间件 Dubbo 和 Spring Cloud,选择了 Dubbo,可以对当前现有项目进行平滑升级改造。但是一开始就遇到了麻烦,自定义异常在传递的过程中变成了 RuntimeException,统一异常处理 GlobalExceptionHandler 无法获取异常信息。
问题重现
项目进行统一异常处理,抽取了一个通用异常 ServiceException,此异常是非受检异常,即继承于 RuntimeException。调研时发现如果服务提供方即 provider 抛出了 ServiceException 异常,consumer 服务消费方就会收到一个 RuntimeException 异常,而 ServiceException 异常的内容被包含在了 RuntimeException 的异常堆栈中
[Request processing failed; nested exception is java.lang.RuntimeException: io.github.mosiki.common.exception.ServiceException: missing_required_parameters
io.github.mosiki.common.exception.ServiceException: missing_required_parameters
at io.github.mosiki.provider.HelloService.sayHello(HelloService.java:20)
at com.alibaba.dubbo.common.bytecode.Wrapper1.invokeMethod(Wrapper1.java)
而我的统一异常处理是这样的,只处理 ServiceException
以及 Exception
,因此就无法获取到原始异常的信息了。
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ServiceException.class)
public Result handlerServiceException(ServiceException ex) {
return Result.failure(ex.getCode(), ex.getMessage());
}
@ExceptionHandler({Exception.class})
public Result handlerException(Exception ex) {
log.error("发生未知异常:{}", ex);
return Result.failure(HttpStatus.INTERNAL_SERVER_ERROR.value(), "服务器打了个小盹儿~请稍候再试");
}
}
访问接口将返回如下,异常中原有信息丢失。
上网搜索发现,这是因为 dubbo 的异常处理类 com.alibaba.dubbo.rpc.filter.ExceptionFilter
进行处理后的结果,Debug 之后确实如此,dubbo 在此进行了转换。
问题解决之道
现在我想要 provider 把自定义的异常原封不动的抛给 consumer 进行处理,于是有了如下思路:
- 禁用 provider 的 ExceptionFilter
- 让 GlobalExceptionHandler 处理 consumer 的异常
按照此思路做就很简单了,网上大多文章的办法都比较麻烦,有用 AOP 处理的,甚至还有让自己修改编译源码上传私服的-_-||,本文给出比较简便的方法,提供参考。
禁用provider的ExceptionFilter
修改 provider 的配置,我这里使用 yml 配置文件,其他类型如 xml/properties 也同理,设置 provider 的 filter 为 -exception,这样异常就不会被处理而是直接抛出了。
dubbo:
application:
name: provider
protocol:
name: dubbo
port: 20100
registry:
address: 127.0.0.1:2181
protocol: zookeeper
provider:
filter: -exception
GlobalExceptionHandler捕获ServiceException
只是禁用了 provider 的 ExceptionHandler 还不能完全达到我们的目的,访问接口,provider 抛出异常 consumer 正确接收为 ServiceException。
[Request processing failed; nested exception is io.github.mosiki.common.exception.ServiceException: missing_required_parameters] with root cause
io.github.mosiki.common.exception.ServiceException: missing_required_parameters
at io.github.mosiki.provider.HelloService.sayHello(HelloService.java:20) ~[na:na]
at com.alibaba.dubbo.common.bytecode.Wrapper1.invokeMethod(Wrapper1.java) ~[na:na]
我们处理一下 GlobalExceptionHandler。
SpringBoot 主要这个启动类的位置和全局异常处理器的位置,一定要保证异常处理器在启动类的同级包或者在启动类的子包当中,否则异常处理器将不生效!
效果展示
以上两步完成后,重启服务,访问接口测试。
拿到了 provider 抛出的原始自定义异常,如此问题就解决了。
代码下载
参考
dubbo自定义异常传递信息丢失问题解决的更多相关文章
- JMeter中添加dubbo相关插件异常问题解决
从网上下载了一个dubbo的插件,然后放到JMeter的/lib/ext目录下: 然后启动直接异常 发现启动不了,然后下载了一个全新的JMeter3.2将dubbo插件放到同样的目录,启动,没有问题: ...
- 找不到mysql.sock,mysql.sock丢失问题解决方法
Can 't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock '(2) "; 是你的mysql ...
- MySQL远程连接丢失问题解决方法Lost connection to MySQL server at ‘reading initial communication packet’, system error: 0
最近远程连接mysql总是提示 Lost connection 很明显这是连接初始化阶段就丢失了连接的错误 其实问题很简单,都是MySQL的配置文件默认没有为远程连接配置好,只需要更改下MySQL的配 ...
- 关于c# SESSION丢失问题解决办法
我们在用C#开发程序的时候经常会遇到Session很不稳定,老是数据丢失.下面就是Session数据丢失的解决办法希望对您有好处.1.在WEB.CONFIG文件中修改SESSION状态保存模式,如:& ...
- caffe.pb.h丢失问题解决方法
https://blog.csdn.net/ThomasCai001/article/details/53940430 错误提示 fatal error: caffe/proto/caffe.pb ...
- AndroidKiller报.smali文件丢失问题解决(关闭Android Studio的Instant Run)
第一节编写一个Android程序里我们生成了一个验证激活码的apk,当我们输入的激活码正确时才能注册成功,输入错误时注册失败. 现在我们想输入错误的激活码也能注册.我们用Android反编译工具进行反 ...
- Unity动态字体在手机上出现字体丢失问题解决
在我们游戏的开发过程中,在部分手机上运行游戏的时候,出现了字体丢失的问题,出问题的手机似乎用的都是高通芯片. 使用的unity是4.2.0版本,ngui是3.4.9版本. 在unity的论坛及unit ...
- SWD下载调试填坑,SWD连接丢失问题解决
野火SWD下载器,设置好以后,第一次下载成功,莫名其妙丢失连接,发现在复位状态可以连接(惊奇) 网络上搜索到把Boot0和Boot1置高,就可以把程序下载到RAM里, 能下载以后就好办了,把程序里SW ...
- MySql权限丢失问题解决
参考文章 [mysql] root权限丢失恢复 完全菜鸟教程 今天用root账户登录到mysql后, show databases 命令返回的只有两个表, 然后使用 use database 命令提示 ...
随机推荐
- 在Linux下部署mysql时,使用group by碰到的问题
mysql使用group by 的时候报错,错误信息如下: 1055:ER_WRONG_FIELD_WITH_GROUP: Expression #2 of SELECT list is not in ...
- MVC+EF 多条件查询
根据以前的做法是拼接sql语句,这会增加维护成本,因为sql语句里的内容不会报错,所以在使用ef的时候必须要抛弃拼接sql语句的习惯. 构建实例 List<vyw_user> list = ...
- 反编译看java for-each循环
java 1.5发行版引入的for-each循环.(引自<Effective Java>中文版第二版 第46条) 如以下对数组列表的for-each循环示例: public class F ...
- Convert Spaces to Tabs
:set tabstop=2 " To match the sample file :set noexpandtab " Use tabs, not spaces :%retab! ...
- python学习第四天笔记整理
一.迭代器及生成器 #迭代器:迭代的工具 #1 什么是迭代:指的是一个重复的过程,每一次重复称为一次迭代,并且每一次重复的结果是下一次重复的初始值# while True:# print('===== ...
- python之路(九)-函数装饰器
装饰器 某公司的基础业务平台如下: def f1(): print('这是f1业务平台') def f2(): print('这是f2业务平台') def f3(): print('这是f3业务平台' ...
- webservice的两种方式SOAP和REST的通俗理解
Webservice代表所有基于web的服务,包含两种方式SOAP和REST 以SOAP为例: 一个RPC call 就是把一个XML文档post到某个URL下,这个xml文档里写明我要调用的函数名和 ...
- Promise实践
一.概念 Promise是异步编程的解决方案之一,与事件驱动+回调函数并列. Promise是专门为异步编程设计的封闭的一次性用品,封闭体现在只有异步操作的结果能改变其状态,其他任何操作都不能改变其状 ...
- java获取当前日期的前一天和后一天
/** * 获得指定日期的前一天 * @param specifiedDay * @return * @throws Exception */ public static String getSpec ...
- Windows 10 IoT Core 17083 for Insider 版本更新
1月26日,微软发布了Windows 10 IoT Core 17083 for Insider版本更新,概括如下: 新特性:1. General bug fixes2. Enabled Flash ...