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