<error-page> tag in web.xml doesn't catch java.lang.Throwable Exceptions

14,546

Solution 1

You should not catch and suppress it, but just let it go.

I.e. do not do:

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    try {
        doSomethingWhichMayThrowException();
    } catch (IllegalArgumentException e) {
        e.printStackTrace(); // Or something else which totally suppresses the exception.
    }
}

But rather just let it go:

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doSomethingWhichMayThrowException();
}

Or, if you actually intented to catch it for logging or so (I'd rather use a filter for that, but ala), then rethrow it:

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    try {
        doSomethingWhichMayThrowException();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
        throw e;
    }
}

Or, if it's not an runtime exception, then rethrow it wrapped in ServletException, it will be automatically unwrapped by the container:

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    try {
        doSomethingWhichMayThrowException();
    } catch (NotARuntimeException e) {
        throw new ServletException(e);
    }
}

See also:

Solution 2

Another (simplified) approach is not to declare multiple handlers for various <error-code> and <exception-type> situations but rather have one, sort of catch-all sink, e.g.

<error-page>
    <location>/error-page.jsp</location>
</error-page>

Inside your error-page.jsp you can determine the cause, be it a return status code or an exception as described here: https://www.tutorialspoint.com/servlets/servlets-exception-handling.htm These constants are a part of the standard Servlet 3.0 API.

For instance a primitive error-page.jsp response handler placed into the root of your webapp can look like this:

Server encountered a situation
Status code: <%=(Integer) request.getAttribute(javax.servlet.RequestDispatcher.ERROR_STATUS_CODE)%>
<br>
Exception: <%=(Throwable) request.getAttribute(javax.servlet.RequestDispatcher.ERROR_EXCEPTION)%>

For security reasons I wouldn't recommend sending the exact exception type to the client; this is just an example of how to handle different types of errors and response statuses inside a JSP handler; a servlet can be used instead of JSP.

One common catch-all handler vs one per status code is certainly dependent on the situation and requirements.

Share:
14,546
andPat
Author by

andPat

Updated on June 05, 2022

Comments

  • andPat
    andPat about 2 years

    I have a web-app developed with servlet & JSP. I configured my app to throw an IllegalArgumentException if I insert bad parameters. Then I configured my web.xml file in this way:

    <error-page>
        <error-code>404</error-code>
        <location>/error.jsp</location>
    </error-page>
    <error-page>
        <exception-type>java.lang.Throwable</exception-type>
        <location>/error.jsp</location>
    </error-page>
    

    When I rise a 404 error, then it works and calls error.jsp, but when I rise a java.lang.IllegalArgumentException, then it does not work and I've a blank page instead of error.jsp. Why?

    The server is Glassfish, and logs show really IllegalArgumentException rised.