You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2001/09/26 19:44:51 UTC

cvs commit: jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/valves ErrorReportValve.java LocalStrings.properties

remm        01/09/26 10:44:51

  Modified:    catalina/src/share/org/apache/catalina/valves
                        ErrorReportValve.java LocalStrings.properties
  Log:
  - Error report and dispatching refactoring.
  - New (and maybe fancier) error reports.
  - HTML code stolen from the Cocoon 2 error reports.
  - The only thing missing is the response reset code (which should not be response.reset,
     but something a bit smarter).
  
  Revision  Changes    Path
  1.2       +192 -17   jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/valves/ErrorReportValve.java
  
  Index: ErrorReportValve.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/valves/ErrorReportValve.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ErrorReportValve.java	2001/09/25 22:11:49	1.1
  +++ ErrorReportValve.java	2001/09/26 17:44:51	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/valves/ErrorReportValve.java,v 1.1 2001/09/25 22:11:49 remm Exp $
  - * $Revision: 1.1 $
  - * $Date: 2001/09/25 22:11:49 $
  + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/valves/ErrorReportValve.java,v 1.2 2001/09/26 17:44:51 remm Exp $
  + * $Revision: 1.2 $
  + * $Date: 2001/09/26 17:44:51 $
    *
    * ====================================================================
    *
  @@ -66,6 +66,9 @@
   
   
   import java.io.IOException;
  +import java.io.PrintWriter;
  +import java.io.StringWriter;
  +import java.io.Writer;
   import java.util.ArrayList;
   import java.util.Enumeration;
   import java.util.Iterator;
  @@ -76,6 +79,7 @@
   import javax.servlet.http.HttpServletRequest;
   import javax.servlet.http.HttpServletResponse;
   import org.apache.catalina.Container;
  +import org.apache.catalina.Globals;
   import org.apache.catalina.HttpRequest;
   import org.apache.catalina.HttpResponse;
   import org.apache.catalina.Logger;
  @@ -84,6 +88,7 @@
   import org.apache.catalina.Valve;
   import org.apache.catalina.ValveContext;
   import org.apache.catalina.connector.HttpResponseWrapper;
  +import org.apache.catalina.util.RequestUtil;
   import org.apache.catalina.util.StringManager;
   
   
  @@ -92,10 +97,14 @@
    *
    * <p>This Valve should be attached at the Host level, although it will work
    * if attached to a Context.</p>
  + * 
  + * <p>HTML code from the Cocoon 2 project.</p>
    *
    * @author Remy Maucherat
    * @author Craig R. McClanahan
  - * @version $Revision: 1.1 $ $Date: 2001/09/25 22:11:49 $
  + * @author <a href="mailto:nicolaken@supereva.it">Nicola Ken Barozzi</a> Aisa
  + * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
  + * @version $Revision: 1.2 $ $Date: 2001/09/26 17:44:51 $
    */
   
   public class ErrorReportValve
  @@ -106,6 +115,12 @@
   
   
       /**
  +     * The debugging detail level for this component.
  +     */
  +    private int debug = 0;
  +
  +
  +    /**
        * The descriptive information related to this implementation.
        */
       private static final String info =
  @@ -151,24 +166,42 @@
                          ValveContext context)
           throws IOException, ServletException {
   
  -        // Skip logging for non-HTTP requests and responses
  -        if (!(request instanceof HttpRequest) ||
  -            !(response instanceof HttpResponse)) {
  -            context.invokeNext(request, response);
  -            return;
  -        }
  -        HttpRequest hrequest = (HttpRequest) request;
  -        HttpResponse hresponse = (HttpResponse) response;
  -        HttpServletRequest hreq =
  -            (HttpServletRequest) hrequest.getRequest();
  -        HttpServletResponse hres =
  -            (HttpServletResponse) hresponse.getResponse();
  -
           // Perform the request
           context.invokeNext(request, response);
   
  +        ServletResponse sresp = response.getResponse();
  +        if (sresp.isCommitted())
  +            return;
  +
  +        ServletRequest sreq = request.getRequest();
  +        Throwable throwable = 
  +            (Throwable) sreq.getAttribute(Globals.EXCEPTION_ATTR);
  +
  +        if (throwable != null) {
  +
  +            // The response is an error
  +            response.setError();
  +
  +            // Reset the response (if possible)
  +            try {
  +                response.getResponse().reset();
  +            } catch (IllegalStateException e) {
  +                ;
  +            }
  +
  +            ServletResponse sresponse = response.getResponse();
  +            if (sresponse instanceof HttpServletResponse)
  +                ((HttpServletResponse) sresponse).sendError
  +                    (HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
   
  +        }
   
  +        try {
  +            report(request, response, throwable);
  +        } catch (Throwable tt) {
  +            tt.printStackTrace();
  +        }
  +
       }
   
   
  @@ -186,6 +219,148 @@
   
   
       // ------------------------------------------------------ Protected Methods
  +
  +
  +    /**
  +     * Prints out an error report.
  +     * 
  +     * @param request The request being processed
  +     * @param response The response being generated
  +     * @param exception The exception that occurred (which possibly wraps
  +     *  a root cause exception
  +     */
  +    protected void report(Request request, Response response,
  +                          Throwable throwable)
  +        throws IOException {
  +
  +        // Do nothing on non-HTTP responses
  +        if (!(response instanceof HttpResponse))
  +            return;
  +        HttpResponse hresponse = (HttpResponse) response;
  +        if (!(response.getResponse() instanceof HttpServletResponse))
  +            return;
  +        HttpServletResponse hres =
  +            (HttpServletResponse) response.getResponse();
  +        int statusCode = hresponse.getStatus();
  +        String message = RequestUtil.filter(hresponse.getMessage());
  +        if (message == null)
  +            message = "";
  +
  +        // Do nothing on a 1xx status
  +        if (statusCode < 200)
  +            return;
  +        // Do nothing on an OK status
  +        if (statusCode == HttpServletResponse.SC_OK)
  +            return;
  +        // Do nothing on a NO MODIFIED status
  +        if (statusCode == HttpServletResponse.SC_NOT_MODIFIED)
  +            return;
  +        // Do nothing on a NO CONTENT status
  +        if (statusCode == HttpServletResponse.SC_NO_CONTENT)
  +            return;
  +
  +        // FIXME: Reset part of the request
  +/*
  +        try {
  +            if (hresponse.isError())
  +                hresponse.reset(statusCode, message);
  +        } catch (IllegalStateException e) {
  +            ;
  +        }
  +*/
  +
  +        Throwable rootCause = null;
  +
  +        if (throwable != null) {
  +
  +            if (throwable instanceof ServletException)
  +                rootCause = ((ServletException) throwable).getRootCause();
  +
  +        }
  +
  +        // Do nothing if there is no report for the specified status code
  +        String report = null;
  +        try {
  +            report = sm.getString("http." + statusCode, message);
  +        } catch (Throwable t) {
  +            ;
  +        }
  +        if (report == null)
  +            return;
  +
  +        try {
  +            hres.setContentType("text/html");
  +        } catch (Throwable t) {
  +            if (debug >= 1)
  +                log("status.setContentType", t);
  +        }
  +
  +        StringBuffer sb = new StringBuffer();
  +
  +        sb.append("<html><head><title>");
  +        sb.append(Globals.SERVER_INFO).append(" - ");
  +        sb.append(sm.getString("errorReportValve.errorReport"));
  +        sb.append("</title>");
  +        sb.append("<STYLE><!--H1{font-family : sans-serif,Arial,Tahoma;color : white;background-color : #0086b2;} ");
  +        sb.append("BODY{font-family : sans-serif,Arial,Tahoma;color : black;background-color : white;} ");
  +        sb.append("B{color : white;background-color : #0086b2;} ");
  +        sb.append("HR{color : #0086b2;} ");
  +        sb.append("--></STYLE> ");
  +        sb.append("</head><body>");
  +        sb.append("<h1>").append(Globals.SERVER_INFO).append(" - ");
  +        sb.append(sm.getString("errorReportValve.statusHeader",
  +                               "" + statusCode, message)).append("</h1>");
  +        sb.append("<HR size=\"1\" noshade>");
  +        sb.append("<p><b>type</b> ");
  +        if (throwable != null) {
  +            sb.append(sm.getString("errorReportValve.exceptionReport"));
  +        } else {
  +            sb.append(sm.getString("errorReportValve.statusReport"));
  +        }
  +        sb.append("</p>");
  +        sb.append("<p><b>");
  +        sb.append(sm.getString("errorReportValve.message"));
  +        sb.append("</b> <u>");
  +        sb.append(message).append("</u></p>");
  +        sb.append("<p><b>");
  +        sb.append(sm.getString("errorReportValve.description"));
  +        sb.append("</b> <u>");
  +        sb.append(report);
  +        sb.append("</u></p>");
  +
  +        if (throwable != null) {
  +            StringWriter stackTrace = new StringWriter();
  +            throwable.printStackTrace(new PrintWriter(stackTrace));
  +            sb.append("<p><b>");
  +            sb.append(sm.getString("errorReportValve.exception"));
  +            sb.append("</b> <pre>");
  +            sb.append(stackTrace.toString());
  +            sb.append("</pre></p>");
  +            if (rootCause != null) {
  +                stackTrace = new StringWriter();
  +                rootCause.printStackTrace(new PrintWriter(stackTrace));
  +                sb.append("<p><b>");
  +                sb.append(sm.getString("errorReportValve.rootCause"));
  +                sb.append("</b> <pre>");
  +                sb.append(stackTrace.toString());
  +                sb.append("</pre></p>");
  +            }
  +        }
  +
  +        sb.append("<HR size=\"1\" noshade>");
  +        sb.append("</body></html>");
  +
  +        try {
  +            Writer writer = response.getReporter();
  +            writer.write(sb.toString());
  +            writer.flush();
  +        } catch (IOException e) {
  +            ;
  +        } catch (IllegalStateException e) {
  +            ;
  +        }
  +
  +    }
   
   
       /**
  
  
  
  1.3       +54 -0     jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/valves/LocalStrings.properties
  
  Index: LocalStrings.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/valves/LocalStrings.properties,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- LocalStrings.properties	2000/10/31 23:53:29	1.2
  +++ LocalStrings.properties	2001/09/26 17:44:51	1.3
  @@ -7,3 +7,57 @@
   requestFilterValve.next=No 'next' valve has been configured
   requestFilterValve.syntax=Syntax error in request filter pattern {0}
   valveBase.noNext=Configuration error: No 'next' valve configured
  +
  +# Error report valve
  +errorReportValve.errorReport=Error report
  +errorReportValve.statusHeader=HTTP Status {0} - {1}
  +errorReportValve.exceptionReport=Exception report
  +errorReportValve.statusReport=Status report
  +errorReportValve.message=message
  +errorReportValve.description=description
  +errorReportValve.exception=exception
  +errorReportValve.rootCause=root cause
  +
  +# HTTP status reports
  +http.100=The client may continue ({0}).
  +http.101=The server is switching protocols according to the "Upgrade" header ({0}).
  +http.201=The request succeeded and a new resource ({0}) has been created on the server.
  +http.202=This request was accepted for processing, but has not been completed ({0}).
  +http.203=The meta information presented by the client did not originate from the server ({0}).
  +http.204=The request succeeded but there is no information to return ({0}).
  +http.205=The client should reset the document view which caused this request to be sent ({0}).
  +http.206=The server has fulfilled a partial GET request for this resource ({0}).
  +http.207=Multiple status values have been returned ({0}).
  +http.300=The requested resource ({0}) corresponds to any one of a set of representations, each with its own specific location.
  +http.301=The requested resource ({0}) has moved permanently to a new location.
  +http.302=The requested resource ({0}) has moved temporarily to a new location.
  +http.303=The response to this request can be found under a different URI ({0}).
  +http.304=The requested resource ({0}) is available and has not been modified.
  +http.305=The requested resource ({0}) must be accessed through the proxy given by the "Location" header.
  +http.400=The request sent by the client was syntactically incorrect ({0}).
  +http.401=This request requires HTTP authentication ({0}).
  +http.402=Payment is required for access to this resource ({0}).
  +http.403=Access to the specified resource ({0}) has been forbidden.
  +http.404=The requested resource ({0}) is not available.
  +http.405=The specified HTTP method is not allowed for the requested resource ({0}).
  +http.406=The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers ({0}).
  +http.407=The client must first authenticate itself with the proxy ({0}).
  +http.408=The client did not produce a request within the time that the server was prepared to wait ({0}).
  +http.409=The request could not be completed due to a conflict with the current state of the resource ({0}).
  +http.410=The requested resource ({0}) is no longer available, and no forwarding address is known.
  +http.411=This request cannot be handled without a defined content length ({0}).
  +http.412=A specified precondition has failed for this request ({0}).
  +http.413=The request entity is larger than the server is willing or able to process.
  +http.414=The server refused this request because the request URI was too long ({0}).
  +http.415=The server refused this request because the request entity is in a format not supported by the requested resource for the requested method ({0}).
  +http.416=The requested byte range cannot be satisfied ({0}).
  +http.417=The expectation given in the "Expect" request header ({0}) could not be fulfilled.
  +http.422=The server understood the content type and syntax of the request but was unable to process the contained instructions ({0}).
  +http.423=The source or destination resource of a method is locked ({0}).
  +http.500=The server encountered an internal error ({0}) that prevented it from fulfilling this request.
  +http.501=The server does not support the functionality needed to fulfill this request ({0}).
  +http.502=This server received an invalid response from a server it consulted when acting as a proxy or gateway ({0}).
  +http.503=The requested service ({0}) is not currently available.
  +http.504=The server received a timeout from an upstream server while acting as a gateway or proxy ({0}).
  +http.505=The server does not support the requested HTTP protocol version ({0}).
  +http.507=The resource does not have sufficient space to record the state of the resource after execution of this method ({0}).
  
  
  

Re: Hard coding HTML within Catalina...

Posted by Remy Maucherat <rm...@home.com>.
> on 9/26/01 10:44 AM, "remm@apache.org" <re...@apache.org> wrote:
>
> > +        sb.append("<html><head><title>");
> > +        sb.append(Globals.SERVER_INFO).append(" - ");
> > +        sb.append(sm.getString("errorReportValve.errorReport"));
> > +        sb.append("</title>");
> > +        sb.append("<STYLE><!--H1{font-family :
sans-serif,Arial,Tahoma;color
> > : white;background-color : #0086b2;}
>
> I find it extremely funny that Catalina has a JSP engine in it yet there
is
> STILL hard coded HTML in the source code. Let me guess, you don't want a
> dependency on JSP...or even better...trying to do this with JSP would be
> more effort than it is worth. :-)

Have you heard of the error page feature ?
;-)

The Catalina core cannot rely on any particular static resource being
present, so we have to hard code some HTML.

> Think you guys would accept a patch to have all these HTML pages as
Velocity
> templates? :-)

Yeah right. Why not use Cocoon 2 and XSP for the error pages ? ;-)
Note: I'm just kidding, ok, don't even think about it ;-)

> That way, people could customize these pages however they
> wanted to without having to hack source code.

They can do that, using the standard error page feature.

Remy


Hard coding HTML within Catalina...

Posted by Jon Stevens <jo...@latchkey.com>.
on 9/26/01 10:44 AM, "remm@apache.org" <re...@apache.org> wrote:

> +        sb.append("<html><head><title>");
> +        sb.append(Globals.SERVER_INFO).append(" - ");
> +        sb.append(sm.getString("errorReportValve.errorReport"));
> +        sb.append("</title>");
> +        sb.append("<STYLE><!--H1{font-family : sans-serif,Arial,Tahoma;color
> : white;background-color : #0086b2;}

I find it extremely funny that Catalina has a JSP engine in it yet there is
STILL hard coded HTML in the source code. Let me guess, you don't want a
dependency on JSP...or even better...trying to do this with JSP would be
more effort than it is worth. :-)

Think you guys would accept a patch to have all these HTML pages as Velocity
templates? :-) That way, people could customize these pages however they
wanted to without having to hack source code.

-jon