/** * Handle an HTTP status code or Java exception by forwarding control to the location included in * the specified errorPage object. It is assumed that the caller has already recorded any request * attributes that are to be forwarded to this page. Return <code>true</code> if we successfully * utilized the specified error page location, or <code>false</code> if the default error report * should be rendered. * * @param request The request being processed * @param response The response being generated * @param errorPage The errorPage directive we are obeying */ private boolean custom(Request request, Response response, ErrorPage errorPage) { if (container.getLogger().isDebugEnabled()) container.getLogger().debug("Processing " + errorPage); try { // Forward control to the specified location ServletContext servletContext = request.getContext().getServletContext(); RequestDispatcher rd = servletContext.getRequestDispatcher(errorPage.getLocation()); if (response.isCommitted()) { // Response is committed - including the error page is the // best we can do rd.include(request.getRequest(), response.getResponse()); } else { // Reset the response (keeping the real error code and message) response.resetBuffer(true); response.setContentLength(-1); rd.forward(request.getRequest(), response.getResponse()); // If we forward, the response is suspended again response.setSuspended(false); } // Indicate that we have successfully processed this custom page return (true); } catch (Throwable t) { ExceptionUtils.handleThrowable(t); // Report our failure to process this custom page container.getLogger().error("Exception Processing " + errorPage, t); return (false); } }
/** * Invoke the next Valve in the sequence. When the invoke returns, check the response state, and * output an error report is necessary. * * @param request The servlet request to be processed * @param response The servlet response to be created * @exception IOException if an input/output error occurs * @exception ServletException if a servlet error occurs */ @Override public void invoke(Request request, Response response) throws IOException, ServletException { // Perform the request getNext().invoke(request, response); if (response.isCommitted()) { return; } Throwable throwable = (Throwable) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION); if (request.isAsyncStarted() && response.getStatus() < 400 && throwable == null) { return; } if (throwable != null) { // The response is an error response.setError(); // Reset the response (if possible) try { response.reset(); } catch (IllegalStateException e) { // Ignore } response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } response.setSuspended(false); try { report(request, response, throwable); } catch (Throwable tt) { ExceptionUtils.handleThrowable(tt); } if (request.isAsyncStarted()) { request.getAsyncContext().complete(); } }