How do I suppress Jetty 8's default ErrorHandler?

3.1k Views Asked by At

Jetty is helping my application too much. Whenever some unhandled Exception leaks out the top, Jetty takes it upon itself to build a very verbose response and spam it onto my clients

HTTP/1.1 500 com.mongodb.MongoException: No replica set members available in [ { address:'localhost/127.0.0.1:27017', ok:true, ping:0.49878865, isMaster:false, isSecondary:true, setName:dmReplSet, maxBsonObjectSize:16777216, },{ address:'localhost/127.0.0.1:27018', ok:true, ping:0.2565605, isMaster:false, isSecondary:true, setName:dmReplSet, maxBsonObjectSize:16777216, } ] for { "mode" : "primary"}

along with 14K of stacktrace wrapped in a very nice HTML page. The problem is, I don't want the details of the issue leaking out to the clients and, further, this is a JSON Web App accepting and emitting application/json content NOT the HTML Jetty has decided my clients want. I would like to suppress this default error handling having Jetty emit just that standard HTTP 500 response

HTTP/1.1 500 Internal Server Error

and no body at all. How do I get this done? It seems like I should be able to just tell Jetty to "no error page" in etc/jetty.xml or etc/jetty-webdefault.xml or something.

1

There are 1 best solutions below

0
On BEST ANSWER

So this seems most easily solved without binding myself to Jetty too much by <error-page> in web.xml

<servlet>
    <servlet-name>ErrorHandler</servlet-name>
    <servlet-class>device.webapp.ErrorHandler</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>ErrorHandler</servlet-name>
    <url-pattern>/ErrorHandler</url-pattern>
</servlet-mapping>

<error-page>
    <exception-type>java.lang.Throwable</exception-type >
    <location>/ErrorHandler</location>
</error-page>

Implementing ErrorHandler like

package device.webapp;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.commons.httpclient.*;
import org.slf4j.*;

/**
 * The ErrorHandler is intended to catch all unhandled Throwables (as configured in the web.xml)
 * before they get out to Jetty's verbose ErrorHandler.
 * 
 */
public class ErrorHandler extends HttpServlet {

    private static final long serialVersionUID = 1L;
    private Logger log = LoggerFactory.getLogger( ErrorHandler.class );

    @Override
    protected void service( HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException {
        // Analyze the servlet exception
        Throwable throwable = (Throwable) req.getAttribute( "javax.servlet.error.exception" );
        String message = String.format(
                "Responding 500 - Server Error on URI %s",
                req.getAttribute( "javax.servlet.error.request_uri" ) );
        if ( throwable != null ) {
            log.error( message, throwable );
        } else {
            log.warn( "Throwable should not be null!" );
            log.error( message );
        }

        /*
         * Interestingly enough, you can't resp.sendError( 500, "Server Error" ) without triggering
         * Jetty's DefaultErrorHandler which is the core of the problem we are trying to solve!
         */
        resp.setStatus( HttpStatus.SC_INTERNAL_SERVER_ERROR );
    }
}

It isn't pretty, but it works.