前段时间在调试项目中某个功能的时候,由于是在测试环境中,所以在通过RPC框架调用某个远程服务获取相关信息的时候,抛出了一个UndeclaredThrowableException。JDK的java doc是这么解释UndeclaredThrowableException的:如果代理实例的调用处理程序的 invoke 方法抛出一个经过检查的异常(不可分配给 RuntimeException 或 Error 的 Throwable),且该异常不可分配给该方法的throws子局声明的任何异常类,则由代理实例上的方法调用抛出此异常。
明白了什么是UndeclaredThrowableException后,那我就查我的代码中时什么原因导致了这个exception,最后查到是RPC client在调用远程服务的时候,因为测试环境不稳定,等待超时,抛出了一个TimeOutException,而这个TimeOutException不是业务方法所声明的异常,因此就被包装成UndeclaredThrowableException抛出了。这是一个RuntimeException,RPC框架及我的应用(我看了下公司相关项目的代码,也基本都没有处理这个RuntimeException)都没有处理这个异常,那么如果是一个Web项目,这个异常会被容器捕捉到,并给用户展示出一个容器缺省的错误页面,并抛一个500的server错误,如下图所示:
这样的页面展示给用户看,即不友好也不专业/:^_^。那我就想在什么地方可以处理这个异常,然后进行相关处理呢?就上面这个例子来看,这个异常总共途径了一下几个系统:
RPC client(源头)--->我的应用---->Web容器(容器层)
那么我们来分析下,分别在那一层处理这个异常比较合适。
1、源头RPC client层:我认为,判断一处代码是应该处理异常还是将异常抛出,取决于其是否获取了异常信息后,能如何应对?如果其能针对捕捉到的异常做出符合业务逻辑需要的处理,那么就不应该讲异常继续抛出,反之,则抛出异常。比如上面的TimeOutException,不同应用的业务逻辑有不同的处理办法,而RPC Client端并不知道这个具体的情况,所以RPC Client不需要处理这类异常,将其继续抛出即可。越接近异常的源头,处理异常最方便(此处的方便,指的是,在接近于源头的底层框架处理异常,那么对调用这些框架的应用代码来说,就不需要关注异常处理了,这就方便了)
2、应用层:那么是不是需要在应用层做处理呢?这里需要具体情况具体分析。拿我这个应用来说,这是一个web应用,就算我这个应用对runtimeException不做处理,web容器也会对这个异常进行处理,并不会造成程序的崩溃。但是如果应用层不是web项目,或者应用不是依托在某个容器内,那如果应用层不对这个异常进行处理的话,就没人处理这个异常了,就会直接抛出一个RuntimeException,导致程序挂掉。因此我认为,如果我们在应用中调用RPC等之类的服务,要注意一下几点:
a)此处的调用抛了UndeclaredThrowableException,需要额外的处理不?
b) 如果需要,就要在此处捕捉到这个异常;
c) 如果不需要,那么就要想想,我们的应用把这个异常抛出去,接下来会不会有地方来处理这个异常,如果有,则可以继续抛出?
d)如果我们的应用已经是异常处理链中的最后一环,那么还是要把这个异常捕捉住。
e)如果有Web容器之类的罩着,我们可以把这个异常继续传递下去。
如果在应用中要处理异常,应该考虑的全面细致。是否需要降级?该流程是否是必须流程,如果是必须流程是否还会涉及到业务回滚,如果是非必须流程如何在产生异常时不影响当前业务。是否需要容灾?尤其是在电子商务和金融方面,异常的产生是否需要保持财务信息的清晰正常。即使发生不可控异常,支出与收入信息是否可控,不因异常导致非正常的支出与收入等待。
3、Web容器:上面说了,如果是Web项目,容器会处理应用抛出的RuntimeException,就像上面图展示的JBoss Web容器的默认Error页面。但是这样的页面实在是太丑陋了,很不专业。/:^_^。因此我们需要告诉Web容器,当出现某某错误的时候,就展示相应的我们准备好的相应的错误页面。我们只要通过下面的简单配置就可以让Web容器显示漂亮的错误页面:
<error-page>
<error-code>500</error-code>
<location>/error.vm</location>
</error-page>
另外,
对于RPC之类等涉及网络的服务调用,肯定会存在不同情况的异常,开发人员如果不考虑这个的话,那就不知道会出现多少问题,那就是一个不好的编程习惯。
异常的处理是个大学问啊. /:^_^。记录一下,以便以后查看
- 大小: 14.4 KB
分享到:
相关推荐
对于客户机,EntityBean是一种持久性对象,它代表一个存储在持久性存储器中的实体的对象视图,或是一个由现有企业应用程序实现的实体。 Session Bean 还可以再细分为 Stateful Session Bean 与 Stateless Session ...
写一个方法,实现字符串的反转,如:输入abc,输出cba 写一个方法,实现字符串的替换,如:输入bbbwlirbbb,输出bbbhhtccc。 3.数据类型之间的转换 如何将数值型字符转换为数字(Integer,Double) 如何将数字...
SessionBean: Stateless Session Bean 的生命周期是由容器决定的,当客户机发出请求要建立一个Bean的实例时,EJB容器不一定要创建一个新的Bean的实例供客户机调用,而是随便找一个现有的实例提供给客户机。...
在使用Java动态代理时出现了一个很棘手的问题,实现类里抛出了一个自定义异常,但外面捕获不到。 虽然使用 printStack 可以输出调试信息,但通过 getMessage 获取不到提示,因为项目需求是捕捉到同一种自定义异常...
数据来源:中国电力统计NJ-2021版
数据来源:中国电力统计NJ-2021版
词根单词 2.2.4 修改版.apk
毕业论文-基于JSP的个人通讯录管理系统设计与实现.docx
数据来源:中国电力统计NJ-2021版
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
数据来源:中国电力统计NJ-2021版
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
数据来源:中国人口与就业统计NJ-2023版
图书借阅管理系统设计与实现及论大学生写作能力.docx
Smart继电器编程器操作手册
毕业设计论文-基于C的人事管理系统设计与实现.docx
数据来源:中国劳动统计NJ-2023版
OPCEV096IPHT手册
数据来源:中国电力统计NJ-2021版
数据来源:中国人口与就业统计NJ-2023版