Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/catalina/valves/ErrorReportValve.java


1   /*
2    * Copyright 1999-2001,2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  
18  package org.apache.catalina.valves;
19  
20  
21  import java.io.IOException;
22  import java.io.Writer;
23  
24  import javax.servlet.ServletException;
25  import javax.servlet.ServletRequest;
26  import javax.servlet.ServletResponse;
27  import javax.servlet.http.HttpServletResponse;
28  
29  import org.apache.catalina.Globals;
30  import org.apache.catalina.connector.Request;
31  import org.apache.catalina.connector.Response;
32  import org.apache.catalina.util.RequestUtil;
33  import org.apache.catalina.util.ServerInfo;
34  import org.apache.catalina.util.StringManager;
35  import org.apache.tomcat.util.IntrospectionUtils;
36  import org.apache.tomcat.util.compat.JdkCompat;
37  
38  /**
39   * <p>Implementation of a Valve that outputs HTML error pages.</p>
40   *
41   * <p>This Valve should be attached at the Host level, although it will work
42   * if attached to a Context.</p>
43   *
44   * <p>HTML code from the Cocoon 2 project.</p>
45   *
46   * @author Remy Maucherat
47   * @author Craig R. McClanahan
48   * @author <a href="mailto:nicolaken@supereva.it">Nicola Ken Barozzi</a> Aisa
49   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
50   * @author Yoav Shapira
51   * @version $Revision: 304023 $ $Date: 2005-07-26 08:45:22 -0400 (Tue, 26 Jul 2005) $
52   */
53  
54  public class ErrorReportValve
55      extends ValveBase {
56  
57  
58      // ----------------------------------------------------- Instance Variables
59  
60  
61      /**
62       * The descriptive information related to this implementation.
63       */
64      private static final String info =
65          "org.apache.catalina.valves.ErrorReportValve/1.0";
66  
67  
68      /**
69       * The StringManager for this package.
70       */
71      protected static StringManager sm =
72          StringManager.getManager(Constants.Package);
73  
74  
75      // ------------------------------------------------------------- Properties
76  
77  
78      /**
79       * Return descriptive information about this Valve implementation.
80       */
81      public String getInfo() {
82  
83          return (info);
84  
85      }
86  
87  
88      // --------------------------------------------------------- Public Methods
89  
90  
91      /**
92       * Invoke the next Valve in the sequence. When the invoke returns, check
93       * the response state, and output an error report is necessary.
94       *
95       * @param request The servlet request to be processed
96       * @param response The servlet response to be created
97       *
98       * @exception IOException if an input/output error occurs
99       * @exception ServletException if a servlet error occurs
100      */
101     public void invoke(Request request, Response response)
102         throws IOException, ServletException {
103 
104         // Perform the request
105         getNext().invoke(request, response);
106 
107         ServletRequest sreq = (ServletRequest) request;
108         Throwable throwable =
109             (Throwable) sreq.getAttribute(Globals.EXCEPTION_ATTR);
110 
111         ServletResponse sresp = (ServletResponse) response;
112         if (sresp.isCommitted()) {
113             return;
114         }
115 
116         if (throwable != null) {
117 
118             // The response is an error
119             response.setError();
120 
121             // Reset the response (if possible)
122             try {
123                 sresp.reset();
124             } catch (IllegalStateException e) {
125                 ;
126             }
127 
128             response.sendError
129                 (HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
130 
131         }
132 
133         response.setSuspended(false);
134 
135         try {
136             report(request, response, throwable);
137         } catch (Throwable tt) {
138             ;
139         }
140 
141     }
142 
143 
144     // ------------------------------------------------------ Protected Methods
145 
146 
147     /**
148      * Prints out an error report.
149      *
150      * @param request The request being processed
151      * @param response The response being generated
152      * @param throwable The exception that occurred (which possibly wraps
153      *  a root cause exception
154      */
155     protected void report(Request request, Response response,
156                           Throwable throwable)
157         throws IOException {
158 
159         // Do nothing on non-HTTP responses
160         int statusCode = response.getStatus();
161 
162         // Do nothing on a 1xx, 2xx and 3xx status
163         // Do nothing if anything has been written already
164         if ((statusCode < 400) || (response.getContentCount() > 0))
165             return;
166 
167         Throwable rootCause = null;
168 
169         if (throwable != null) {
170 
171             if (throwable instanceof ServletException)
172                 rootCause = ((ServletException) throwable).getRootCause();
173 
174         }
175 
176         String message = RequestUtil.filter(response.getMessage());
177         if (message == null)
178             message = "";
179 
180         // Do nothing if there is no report for the specified status code
181         String report = null;
182         try {
183             report = sm.getString("http." + statusCode, message);
184         } catch (Throwable t) {
185             ;
186         }
187         if (report == null)
188             return;
189 
190         StringBuffer sb = new StringBuffer();
191 
192         sb.append("<html><head><title>");
193         sb.append(ServerInfo.getServerInfo()).append(" - ");
194         sb.append(sm.getString("errorReportValve.errorReport"));
195         sb.append("</title>");
196         sb.append("<style><!--");
197         sb.append(org.apache.catalina.util.TomcatCSS.TOMCAT_CSS);
198         sb.append("--></style> ");
199         sb.append("</head><body>");
200         sb.append("<h1>");
201         sb.append(sm.getString("errorReportValve.statusHeader",
202                                "" + statusCode, message)).append("</h1>");
203         sb.append("<HR size=\"1\" noshade=\"noshade\">");
204         sb.append("<p><b>type</b> ");
205         if (throwable != null) {
206             sb.append(sm.getString("errorReportValve.exceptionReport"));
207         } else {
208             sb.append(sm.getString("errorReportValve.statusReport"));
209         }
210         sb.append("</p>");
211         sb.append("<p><b>");
212         sb.append(sm.getString("errorReportValve.message"));
213         sb.append("</b> <u>");
214         sb.append(message).append("</u></p>");
215         sb.append("<p><b>");
216         sb.append(sm.getString("errorReportValve.description"));
217         sb.append("</b> <u>");
218         sb.append(report);
219         sb.append("</u></p>");
220 
221         if (throwable != null) {
222 
223             String stackTrace = JdkCompat.getJdkCompat()
224                 .getPartialServletStackTrace(throwable);
225             sb.append("<p><b>");
226             sb.append(sm.getString("errorReportValve.exception"));
227             sb.append("</b> <pre>");
228             sb.append(RequestUtil.filter(stackTrace));
229             sb.append("</pre></p>");
230 
231             while (rootCause != null) {
232                 stackTrace = JdkCompat.getJdkCompat()
233                     .getPartialServletStackTrace(rootCause);
234                 sb.append("<p><b>");
235                 sb.append(sm.getString("errorReportValve.rootCause"));
236                 sb.append("</b> <pre>");
237                 sb.append(RequestUtil.filter(stackTrace));
238                 sb.append("</pre></p>");
239                 // In case root cause is somehow heavily nested
240                 try {
241                     rootCause = (Throwable)IntrospectionUtils.getProperty
242                                                 (rootCause, "rootCause");
243                 } catch (ClassCastException e) {
244                     rootCause = null;
245                 }
246             }
247 
248             sb.append("<p><b>");
249             sb.append(sm.getString("errorReportValve.note"));
250             sb.append("</b> <u>");
251             sb.append(sm.getString("errorReportValve.rootCauseInLogs",
252                                    ServerInfo.getServerInfo()));
253             sb.append("</u></p>");
254 
255         }
256 
257         sb.append("<HR size=\"1\" noshade=\"noshade\">");
258         sb.append("<h3>").append(ServerInfo.getServerInfo()).append("</h3>");
259         sb.append("</body></html>");
260 
261         try {
262             try {
263                 response.setContentType("text/html");
264                 response.setCharacterEncoding("utf-8");
265             } catch (Throwable t) {
266                 if (container.getLogger().isDebugEnabled())
267                     container.getLogger().debug("status.setContentType", t);
268             }
269             Writer writer = response.getReporter();
270             if (writer != null) {
271                 // If writer is null, it's an indication that the response has
272                 // been hard committed already, which should never happen
273                 writer.write(sb.toString());
274             }
275         } catch (IOException e) {
276             ;
277         } catch (IllegalStateException e) {
278             ;
279         }
280         
281     }
282 
283 
284 }