4

Server errors result in HTTP 500-responses to the client with a generic error message ("The server encountered an error..."). Is there any way to intercept this message and write a custom one?

I'm would like to have a way to uniquely identify a server error from the client. If I could for instance generate a GUID which I logged server-side upon a server error and then send that ID to the client, that would make it easy to search for that particular exception in the log at any point later in time.

I do realize that server errors are generated by exceptions in the code, so I'm looking for some kind of catch all exception hook in the app engine API. Of course, if such a hook exists, and the code which executes here generates a second exception, it would have to default to the general 500-error again.

I'm using the Java API for GAE

Nilzor
  • 18,082
  • 22
  • 100
  • 167
  • 1
    You didn't mention if your using python or java. Python error display https://developers.google.com/appengine/docs/python/config/appconfig#Custom_Error_Responses – Tim Hoffman Apr 18 '13 at 15:43
  • Sorry. I am using Java. Found a similar document for Java so I might be able to use that : https://developers.google.com/appengine/docs/java/config/appconfig#Custom_Error_Responses – Nilzor Apr 18 '13 at 16:13

3 Answers3

2

For GAE generated errors you can configure a custom error page. For errors generated by your code you should use a catch-all wrapper inside a first servlet filter.

Peter Knego
  • 79,991
  • 11
  • 123
  • 154
1

I ended up coding a Servlet Filter by following the answer in this SO question. The filter wraps the doFilter() call in a general try-catch block and creates a reference number for the client while logging it at the server. I think this little snippet might be useful for others out there:

public class ExceptionFilter implements Filter {
    private FilterConfig filterConfig;

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
        throws IOException, ServletException {

        try {
            filterChain.doFilter(request, response);
        }
        catch (Exception ex) {
            String errorId = UUID.randomUUID().toString();
            Mylog.e("Server error " + errorId); // Use whatever logging mechanizm you prefer
            String clientResponse = "Server error. Reference no: " + errorId;     
            ((HttpServletResponse) response).setStatus(500);                
            response.getWriter().write(clientResponse);
        }
    }

    public FilterConfig getFilterConfig() {
        return filterConfig;
    }

    public void init(FilterConfig filterConfig) {
        this.filterConfig = filterConfig;
    }

    public void destroy() {}      
}

You also need to configure web.xml like this (goes somewhere under the <web app> tag):

<filter>
    <filter-name>ExceptionFilter</filter-name>
    <filter-class>your.package.ExceptionFilter</filter-class>
</filter>
<filter-mapping>
   <filter-name>ExceptionFilter</filter-name>
    <servlet-name>Your Servlet Name As Defined In servlet-mapping</servlet-name>
</filter-mapping>
Community
  • 1
  • 1
Nilzor
  • 18,082
  • 22
  • 100
  • 167
0

You didn't mention if your using python or java. Python error display https://developers.google.com/appengine/docs/python/config/appconfig#Custom_Error_Responses

Note these are just static pages that are shown in the event of any uncaught errors.

You can try and catch these errors in your main handler (I am talking about python), but you can't always. For instance you maybe able to catch a DeadlineExceededError some times, and you may have a tiny bit of time to emit a log, or a redirect (maybe to the same page to try again or to your own static page, with an arg with the GUID you mentioned, then have javascript render it some useful way) but often that won't work. So it very much depends on the nature of the error.

Tim Hoffman
  • 12,976
  • 1
  • 17
  • 29