Tuesday, August 19, 2014

Tomcat Suppress Stacktrace on Status 500 Error Page for REST Services

Whenever there is a HTTP Status 500 error, Tomcat by default displays an error page with the stacktrace on it. In production servers, this should be disabled. One common way to do this is to specify custom error pages in web.xml, like this:
<error-page>
<error-code>500</error-code>
<location>/error-500.html</location>
</error-page>

This works in most cases, but for a lot of Java REST backends, all URLs are mapped to the REST framework. For example, with Jersey, all URLs are mapped to the Servlet handling the REST requests.
<servlet-mapping>
<servlet-name>RestServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
In this situation the above solution will fail because RestServlet is unable to serve "error-500.html".

The solution is to use another Servlet to handle error paths. For static files, the "default" Servlet works. In order for Tomcat to use the default Servlet for error pages, this has to appear before the RestServlet in web.xml.
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/error*</url-pattern>
</servlet-mapping>

However, there is a problem with this solution. If the original REST request is a PUT, the default Servlet will reject it with a 403. The solution is to create a custom error handling Servlet that does not process the request but instead prints out the error page depending on the error code embedded in the request URI. This is a Servlet that overrides doGet, doPost, doPut and doDelete, and within each of them, outputs the appropriate error page using out.print().

No comments:

Post a Comment