`

由一个UndeclaredThrowableException带来的思考

阅读更多


前段时间在调试项目中某个功能的时候,由于是在测试环境中,所以在通过RPC框架调用某个远程服务获取相关信息的时候,抛出了一个UndeclaredThrowableException。JDK的java doc是这么解释UndeclaredThrowableException的:如果代理实例的调用处理程序的 invoke 方法抛出一个经过检查的异常(不可分配给 RuntimeException  Error  Throwable),且该异常不可分配给该方法的throws子局声明的任何异常类,则由代理实例上的方法调用抛出此异常

明白了什么是UndeclaredThrowableException后,那我就查我的代码中时什么原因导致了这个exception,最后查到是RPC client在调用远程服务的时候,因为测试环境不稳定,等待超时,抛出了一个TimeOutException,而这个TimeOutException不是业务方法所声明的异常,因此就被包装成UndeclaredThrowableException抛出了。这是一个RuntimeException,RPC框架及我的应用(我看了下公司相关项目的代码,也基本都没有处理这个RuntimeException)都没有处理这个异常,那么如果是一个Web项目,这个异常会被容器捕捉到,并给用户展示出一个容器缺省的错误页面,并抛一个500server错误,如下图所示:500


这样的页面展示给用户看,即不友好也不专业/:^_^。那我就想在什么地方可以处理这个异常,然后进行相关处理呢?就上面这个例子来看,这个异常总共途径了一下几个系统:


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
分享到:
评论
1 楼 sp42 2018-01-02  
可否处理下排版?

相关推荐

Global site tag (gtag.js) - Google Analytics