奇怪的Java异常行为

时间:2016-03-10 08:32:30

标签: java google-app-engine exception-handling google-cloud-endpoints

我正在使用带有云端点的Google App Engine。 我注意到Java异常处理中有一个奇怪的事情。

考虑这个异常堆栈

com.google.api.server.spi.response.ForbiddenException: Unable to find an organization(4)-user(1) match.
    at com.fms.advocacy.api.auth.JwtUser.getUserFromRequest(JwtUser.java:172)
    at com.fms.advocacy.api.user_profile.UserProfileApi.getCurrentUserProfile(UserProfileApi.java:150)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:130)
    at com.google.api.server.spi.SystemService.invokeServiceMethod(SystemService.java:363)
    at com.google.api.server.spi.SystemServiceServlet.execute(SystemServiceServlet.java:113)
    at com.google.api.server.spi.SystemServiceServlet.doPost(SystemServiceServlet.java:71)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
    at com.fms.advocacy.filters.AccessRuleFilter.doFilter(AccessRuleFilter.java:67)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.fms.advocacy.filters.AuthFilter.doFilter(AuthFilter.java:48)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.fms.advocacy.filters.CorsFilter.doFilter(CorsFilter.java:27)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.fms.advocacy.filters.ErrorHandlerFilter.doFilter(ErrorHandlerFilter.java:38)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.api.socket.dev.DevSocketFilter.doFilter(DevSocketFilter.java:74)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)

此处getUserFromRequest方法抛出异常。 正如您所看到的,它是从过滤器ErrorHandlerFilter>链接而来的。 CorsFilter> AuthFilter> AccessRuleFilter。

在ErrorHandlerFilter过滤器中,我写了一个像

这样的代码
 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        try { 
            chain.doFilter(request, response);
        } catch (Throwable throwable) { 
            System.out.println("Got " + throwable.getMessage());
        }
    }

理想情况下,客户端不应该收到任何内容,并且消息应该在我的控制台中打印。但两者都没有发生。相反,客户收到了以下回复。

{
  "error" : {
    "message" : "Unable to find an organization(4)-user(1) match.",
    "code" : 403,
    "errors" : [ {
      "domain" : "global",
      "reason" : "forbidden",
      "message" : "Unable to find an organization(4)-user(1) match."
    } ]
  }
}

为什么会这样?

1 个答案:

答案 0 :(得分:1)

抛出的异常在它到达ErrorHandlerFilter中的catch子句之前被捕获。

我不熟悉google-app-engine,但我认为它是由com.google.api.server.spi.SystemServiceServlet完成的,因为异常很好地包装在json中并且不会传播。

所以,从ErrorHandlerFilter.doFilter()方法的角度来看,一切都很顺利。当chain.doFilter(request, response);返回时,json with已经写入response的输出流。