Harikrishnan
Harikrishnan

Reputation: 3822

Weird Java Exception Behaviour

I am using Google App Engine with Cloud Endpoints. I have noticed a weird thing in Java exception handling in it.

Consider this exception stack

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)

Here the exception is thrown by getUserFromRequest method. As you can see, it is chained from the filters ErrorHandlerFilter > CorsFilter > AuthFilter > AccessRuleFilter.

In ErrorHandlerFilter filter I wrote a code like,

 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());
        }
    }

So ideally, the client should not receive anything, and the message should print in my console. But both are not happening. instead the client received the following response.

{
  "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."
    } ]
  }
}

Why is it like that?

Upvotes: 0

Views: 105

Answers (1)

Vladimir
Vladimir

Reputation: 9753

The exception thrown is caught before it gets to your catch clause in ErrorHandlerFilter.

I'm not familiar with google-app-engine, but I suppose it's done by com.google.api.server.spi.SystemServiceServlet, since exception is nicely wrapped in json and is not propagated furher.

So, from the ErrorHandlerFilter.doFilter() method's point of view, everything went fine. When chain.doFilter(request, response); returns, json with is written to response's output stream already.

Upvotes: 1

Related Questions