访问我的博客

目前计划对已有的单体项目进行组织架构拆分,调研了分布式系统中常用中间件 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_parametersat 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 进行处理,于是有了如下思路:

  1. 禁用 provider 的 ExceptionFilter
  2. 让 GlobalExceptionHandler 处理 consumer 的异常

按照此思路做就很简单了,网上大多文章的办法都比较麻烦,有用 AOP 处理的,甚至还有让自己修改编译源码上传私服的-_-||,本文给出比较简便的方法,提供参考。

禁用provider的ExceptionFilter

修改 provider 的配置,我这里使用 yml 配置文件,其他类型如 xml/properties 也同理,设置 provider 的 filter 为 -exception,这样异常就不会被处理而是直接抛出了。

dubbo:application:name: providerprotocol:name: dubboport: 20100registry:address: 127.0.0.1:2181protocol: zookeeperprovider: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 causeio.github.mosiki.common.exception.ServiceException: missing_required_parametersat 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 抛出的原始自定义异常,如此问题就解决了。

代码下载

  • https://github.com/Mosiki/dubbo-exception-example-parent

参考

  • https://blog.csdn.net/yangzaizi/article/details/80638306

转载于:https://www.cnblogs.com/vcmq/p/10162054.html

dubbo自定义异常传递信息丢失问题解决相关推荐

  1. Dubbo自定义异常message过长解决

    title: Dubbo自定义异常message过长解决 tags: dubbo exception message attachment encode categories: dubbo date: ...

  2. linux rpm找不到命令_Linux实战013:yum工具丢失问题解决(yum安装)

    今天启动本来想在docker上配置个apache的,结果run的时候发现docker没有运行(我记得docker是一直启动的呀,也设置了开机启动的).我先查了下docker服务结果还真没有,那就只能手 ...

  3. nginx 监听非标准端口80,重定向端口丢失问题解决

    nginx 监听非标准端口80,重定向端口丢失问题解决 参考文章: (1)nginx 监听非标准端口80,重定向端口丢失问题解决 (2)https://www.cnblogs.com/qianxunm ...

  4. AndroidKiller报.smali文件丢失问题解决(关闭Android Studio的Instant Run)

    AndroidKiller报.smali文件丢失问题解决(关闭Android Studio的Instant Run) 参考文章: (1)AndroidKiller报.smali文件丢失问题解决(关闭A ...

  5. mysql 遗失对主机的连接,MySQL远程连接丢失问题解决方法(Lost connection to MySQL server)...

    MySQL远程连接丢失问题解决方法(Lost connection to MySQL server) 最近服务器很不稳定,于是重装了mysql 和php 服务,但是接着却遇到了很头疼的麻烦. 远程连接 ...

  6. Office2011 for mac升级到Office2016 for mac后Outlook邮件索引丢失问题解决

    Office2011 for mac升级到Office2016 for mac后Outlook邮件索引丢失问题解决 Office2011 for mac是2016年安装的,微软已经不再维护这个版本,同 ...

  7. html2canvas 图片合成模糊以及保存为图片背景图丢失问题解决

    html2canvas 图片合成模糊以及保存为图片背景图丢失问题解决 注意 作为背景的图片必须放在服务器,存放在本地会出现截图的时候背景图丢失的问题; 背景图必须放在img里面里面,通过定位处理成和背 ...

  8. Unity动态字体在手机上出现字体丢失问题解决

    Unity动态字体在手机上出现字体丢失问题解决 参考文章: (1)Unity动态字体在手机上出现字体丢失问题解决 (2)https://www.cnblogs.com/bicker/p/3669176 ...

  9. 实况2018服务器维护,《实况足球2018》常见dll丢失问题解决方法汇总

    <实况足球2018>常见dll丢失问题解决方法汇总 2017-10-17 10:18:14来源:绿茵吧编辑:评论(0) <实况足球2018>已经发售一段时间,玩家在进入体验式也 ...

最新文章

  1. 如何用Jupyter Notebook制作新冠病毒疫情追踪器?
  2. 计算机科学 在职双证,计算机专业在职研究生如何获得双证?
  3. AI 从业者都会用到的 10 个深度学习方法
  4. 腾讯视频怎么退出青少年守护模式
  5. java nio 消息_java nio消息半包、粘包解决方案
  6. 一个入门级的Java Applet
  7. nginx: [emerg] bind() to 0.0.0.0:66 failed (98: Address already in use)
  8. 微软回应法国指责Win10过度收集隐私数据:将更新隐私声明
  9. 输出IMG格式SAR图像——Img格式图像文件概述
  10. 基于Kinetis系列微控制器K60芯片的I2C接口函数程序说明1
  11. 第四章_思科ASDM网管系统搭建(java环境,jdk环境)
  12. 利用pytesseract进行图片文字识别
  13. C语言捕捉键盘,按键信息
  14. 使用ffpemg无损快速从视频中提取音频的操作教程(记录笔记超详细)
  15. 用html写简单的座位表,html座位表,随机点名
  16. Hack the box: Bastion
  17. 网络攻防|如何让自己的CobaltStrike服务器隐匿(一)
  18. 基于javaweb的人才求职招聘管理系统(java+springboot+freemarker+jpa+mysql)
  19. 《拥抱》---梦中好友s:103
  20. ie input兼容 vue_vue+iview 兼容IE11浏览器的实现方法

热门文章

  1. .NET(C#):警惕PLINQ结果的无序性
  2. php获取ios或android通过文件头(header)传过来的坐标,通过百度接口获取具体城市和地址,并存入到session中...
  3. property_get 与 property_set 的返回值(转载)
  4. SliverLight Web part
  5. CXF2.7.3 与spring 3集成 .
  6. java面试题标签_java面试笔试题 (WEB)
  7. Docker网络相关
  8. UVA11991第k次出现的v的下标
  9. C语言经典例100-将学生成绩写入文件
  10. 【EventBus】发布-订阅模式 ( EventBus 组成模块 | 观察者模式 )