1 15 package org.jahia.bin; 16 17 25 26 import java.io.File ; 27 import java.io.IOException ; 28 import java.io.PrintWriter ; 29 import java.io.StringWriter ; 30 import java.lang.reflect.InvocationTargetException ; 31 import java.util.Date ; 32 import java.util.Enumeration ; 33 import java.util.Properties ; 34 import java.util.regex.Matcher ; 35 import java.util.regex.Pattern ; 36 37 import javax.mail.Message ; 38 import javax.mail.Session ; 39 import javax.mail.Transport ; 40 import javax.mail.internet.InternetAddress ; 41 import javax.mail.internet.MimeMessage ; 42 import javax.servlet.RequestDispatcher ; 43 import javax.servlet.ServletContext ; 44 import javax.servlet.ServletException ; 45 import javax.servlet.http.HttpServletRequest ; 46 import javax.servlet.http.HttpServletResponse ; 47 48 import org.jahia.exceptions.JahiaException; 49 import org.jahia.settings.SettingsBean; 50 51 63 64 public class JahiaErrorDisplay { 65 66 private static org.apache.log4j.Logger logger = 67 org.apache.log4j.Logger.getLogger(JahiaErrorDisplay.class); 68 69 private static final String DISPATCH_DESTINATION = "/jsp/jahia/errors/error.jsp"; 70 private static final String DISPATCH_DIRECTORY = "/jsp/jahia/errors/"; 71 private static final String DISPATCH_PREFIX="error_"; 72 private static final boolean IS_STACK_INCLUDED = true; 73 74 public static final String DISPLAY_JAHIA_ERROR = "displayJahiaError"; 75 76 static { 77 logger.debug("Initialized with destination = [" + 78 DISPATCH_DESTINATION + "]"); 79 } 80 81 public JahiaErrorDisplay() { 82 } 83 84 89 public static boolean HTMLFallBackDisplay(HttpServletRequest request, HttpServletResponse response, Throwable t) { 90 PrintWriter out = null; 91 try { 92 out = response.getWriter(); 93 } catch (Throwable newt) { 94 return false; 95 } 96 if (out != null) { 97 100 out.println("<html>"); 101 out.println(" <head>"); 102 out.println(" <title>Jahia Error</title>"); 103 out.println(" </head>"); 104 out.println(" <body>"); 105 out.println(" <table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">"); 106 out.println(" <tr>"); 107 out.println(" <td colspan=\"2\"><h1>Jahia Error</h1></td>"); 108 out.println(" </tr>"); 109 out.println(" <tr>"); 110 out.println(" <td colspan=\"2\">An error has occured while Jahia was processing data. Consult the info below for more precise information</td>"); 111 out.println(" </tr>"); 112 out.println(" <tr>"); 113 out.println(" <td>Exception :</td>"); 114 out.println(" <td>" + t.getMessage() + "</td>"); 115 out.println(" </tr>"); 116 if (IS_STACK_INCLUDED) { 117 out.println(" <tr>"); 118 out.println(" <td>Stack trace : </td>"); 119 out.println(" <td><pre>"); 120 String stackTraceStr = stackTraceToString(t); 121 out.println(stackTraceStr); 122 out.println(" </pre></td>"); 123 out.println(" </tr>"); 124 } 125 out.println(" </table>"); 126 out.println(" </body>"); 127 out.println("</html>"); 128 } else { 129 ; 130 } 131 return false; 132 } 133 134 public static boolean DisplayException(HttpServletRequest request, 135 HttpServletResponse response, 136 ServletContext context, 137 Throwable t) { 138 return DisplayException(request, response, context, null, t); 139 } 140 141 public static boolean DisplayException(HttpServletRequest request, 142 HttpServletResponse response, 143 ServletContext context, 144 SettingsBean jSettings, 145 Throwable t) { 146 return DisplayException(request, response, context, jSettings, true, true, t); 147 } 148 149 155 public static boolean DisplayException(HttpServletRequest request, 156 HttpServletResponse response, 157 ServletContext context, 158 SettingsBean jSettings, 159 boolean sendEmail, 160 boolean displayInConsole, 161 Throwable t) { 162 try { 163 164 Boolean displayJahiaError = (Boolean )request.getAttribute(DISPLAY_JAHIA_ERROR); 165 if ( displayJahiaError != null && !displayJahiaError.booleanValue() ){ 166 return false; 167 } 168 169 if ((request == null) || 170 (response == null) || 171 (context == null) || 172 (t == null)) { 173 logger.debug("Can't display exception, not enough information available..."); 174 return false; 175 } 176 context.log(throwableToString(t, request, response)); 178 179 if (response.isCommitted()) { 180 logger.debug("Response already committed, aborting client display, exception has been logged..."); 181 return false; 182 } 183 184 if (displayInConsole) { 185 context.log(throwableToString(t, request, response)); 187 if (t instanceof JahiaException) { 188 JahiaException je = (JahiaException) t; 189 logger.error("ERROR : " + je.getUserErrorMsg() + 190 ", " + je.getJahiaErrorMsg(), getNestedException(t)); 191 } else if (t != null) { 192 logger.error("ERROR : " + t.getMessage(), getNestedException(t)); 193 } 194 } 195 196 String fullPathToDestination = context.getRealPath(DISPATCH_DESTINATION); 198 String contextPathToDestination = DISPATCH_DESTINATION; 199 200 File jspFile = new File (fullPathToDestination); 201 File jspFileErrorCode = null; 202 203 String errorstring = ""; 206 try { 207 errorstring = t.getMessage().trim(); 208 } catch (Throwable tho) {} 209 210 int errorint = 0; 211 212 Pattern p = Pattern.compile("\\d\\d\\d"); 214 Matcher m = p.matcher(errorstring); 215 if (m.find()) 216 errorstring = m.group(); 217 218 try { 219 errorint = Integer.parseInt(errorstring); 220 } catch (NumberFormatException nfe) {} 221 catch (Throwable th) {} 222 223 if (errorint!=0) 225 { 226 response.setStatus(errorint); fullPathToDestination = context.getRealPath (DISPATCH_DIRECTORY + DISPATCH_PREFIX + errorint + ".jsp"); 228 jspFileErrorCode = new File (fullPathToDestination); 229 if (jspFileErrorCode.exists()) 230 { jspFile = jspFileErrorCode; 231 contextPathToDestination = DISPATCH_DIRECTORY + DISPATCH_PREFIX + errorint + ".jsp"; 232 logger.debug("Forwarding error to "+fullPathToDestination); 233 } else { 234 logger.debug("Dispatcher not found at "+fullPathToDestination+ " - using standard error"); 235 } 236 } 237 238 if (jSettings != null) { 239 if (sendEmail) { 240 logger.debug("Jahia Settings available, mailing..."); 241 MailException(t, request, response, jSettings, errorint); 242 } 243 } else { 244 logger.debug("No Jahia Settings, can't mail..."); 245 } 246 247 logger.debug("context is : "+contextPathToDestination); 248 if (jspFile.exists()) { 250 RequestDispatcher dispatcher = context.getRequestDispatcher( contextPathToDestination ); 251 if (dispatcher != null) { 252 request.setAttribute("org.jahia.exception.Message", t.getMessage()); 253 if (IS_STACK_INCLUDED) { 254 String stackTraceStr = stackTraceToString(t); 255 request.setAttribute("org.jahia.exception.StackTrace", stackTraceStr); 256 } 257 dispatcher.forward(request, response); 258 return true; 259 } else { 260 return HTMLFallBackDisplay(request, response, t); 261 } 262 } else { 263 logger.debug("JSP file " + fullPathToDestination + " not found, defaulting to built-in message generator"); 264 return HTMLFallBackDisplay(request, response, t); 265 } 266 267 268 } catch (ServletException se) { 269 logger.debug("JSP caused a Servlet Exception : ", se); 270 logger.debug("Root exception : ", se.getRootCause()); 271 272 } catch (IOException ioe) { 273 logger.debug("Dispatching caused an IOException", ioe); 274 275 } catch (java.lang.IllegalStateException ise) { 276 logger.debug("Cannot forward because response was already committed !", ise); 277 278 } catch (Throwable newt) { 279 logger.debug("Unknown exception during DisplayException : " + t.getMessage(), newt); 280 } 281 return false; 282 } 283 284 288 public static boolean MailException(Throwable t, 289 HttpServletRequest request, 290 HttpServletResponse response, 291 SettingsBean jSettings, 292 int errorInt) { 293 try { 294 String to = null, subject = null, from = null, 295 cc = null, bcc = null, url = null; 296 String mailhost = null; 297 String mailer = "Jahia Server 1.0"; 298 String protocol = null, host = null, user = null, password = null; 299 String record = null; 301 to = jSettings.mail_administrator; 302 from = jSettings.mail_from; 303 mailhost = jSettings.mail_server; 304 305 if ((mailhost.equals("")) || (to.equals("")) || (from.equals(""))) { 306 logger.debug("Mail settings not valid, ignoring..."); 307 return false; 308 } 309 310 if ((mailhost == null) || (to == null) || (from == null)) { 311 logger.debug("Mail settings not valid, ignoring..."); 312 return false; 313 } 314 315 logger.debug("Using settings mailhost=[" + mailhost + 316 "] to=[" + to + "] from=[" + from + 317 "] paranoia=" + 318 Integer.toString(jSettings.mail_paranoia)); 319 320 if (t instanceof JahiaException) { 321 JahiaException je = (JahiaException) t; 322 if (je.getSeverity() < jSettings.mail_paranoia) { 323 return true; 324 } 325 } 326 327 boolean debug = false; 328 329 Properties props = System.getProperties(); 330 if (mailhost != null) 331 props.put("mail.smtp.host", mailhost); 332 333 Session session = Session.getDefaultInstance(props, null); 335 if (debug) 336 session.setDebug(true); 337 338 Message msg = new MimeMessage (session); 340 if (from != null) 341 msg.setFrom(new InternetAddress (from)); 342 else 343 msg.setFrom(); 344 345 msg.setRecipients(Message.RecipientType.TO, 346 InternetAddress.parse(to, false)); 347 if (cc != null) 348 msg.setRecipients(Message.RecipientType.CC, 349 InternetAddress.parse(cc, false)); 350 if (bcc != null) 351 msg.setRecipients(Message.RecipientType.BCC, 352 InternetAddress.parse(bcc, false)); 353 354 subject = "[JAHIA] Jahia Error : " + t.getMessage(); 355 356 msg.setSubject(subject); 357 358 StringWriter msgBodyWriter = new StringWriter (); 359 PrintWriter strOut = new PrintWriter (msgBodyWriter); 360 strOut.println(""); 361 strOut.println("Your Jahia Server has generated an error. Please review the details below for additional information: "); 362 strOut.println(""); 363 if (t instanceof JahiaException) { 364 JahiaException nje = (JahiaException) t; 365 String severityMsg = "Undefined"; 366 switch (nje.getSeverity()) { 367 case JahiaException.WARNING_SEVERITY : severityMsg = "WARNING"; break; 368 case JahiaException.ERROR_SEVERITY : severityMsg = "ERROR"; break; 369 case JahiaException.CRITICAL_SEVERITY : severityMsg = "CRITICAL"; break; 370 case JahiaException.KISSYOURASSGOODBYE_SEVERITY : severityMsg = "FATAL"; break; 371 } 372 strOut.println("Severity : " + severityMsg); 373 } 374 strOut.println(""); 375 strOut.println("Error : " + t.getMessage()); 376 strOut.println(""); 377 strOut.println("URL : " + request.getRequestURL()); 378 if (request.getQueryString() != null) { 379 strOut.println("?" + request.getQueryString()); 380 } 381 strOut.println(" Method : " + request.getMethod()); 382 strOut.println(""); 383 strOut.println("Remote host : " + request.getRemoteHost() + " Remote Address : " + request.getRemoteAddr()); 384 strOut.println(""); 385 strOut.println("Request headers : "); 386 Enumeration headerNames = request.getHeaderNames(); 387 while (headerNames.hasMoreElements()) { 388 String headerName = (String ) headerNames.nextElement(); 389 String headerValue = request.getHeader(headerName); 390 strOut.println(" " + headerName + ":" + headerValue); 391 } 392 if (errorInt == 0) { 393 strOut.println(""); 394 strOut.println("Stack trace : "); 395 String stackTraceStr = stackTraceToString(t); 396 strOut.println(stackTraceStr); 397 } 398 strOut.println(""); 399 strOut.println("Depending on the severity of this error, Jahia may still be operational or not. Please check your"); 400 strOut.println("installation as soon as possible."); 401 strOut.println(""); 402 strOut.println("Yours Faithfully, "); 403 strOut.println(" Jahia Server"); 404 405 msg.setText(msgBodyWriter.toString()); 406 407 msg.setHeader("X-Mailer", mailer); 408 msg.setSentDate(new Date ()); 409 410 logger.debug("Mailing to " + to + " via " + mailhost + "..."); 411 412 Transport.send(msg); 414 415 logger.debug("Mail was sent successfully."); 416 417 } catch (Throwable th) { 418 logger.debug("Error while sending mail : " + th.getMessage(), th); 419 return false; 420 } 421 422 return true; 423 } 424 425 438 private static String throwableToString(Throwable t, 439 HttpServletRequest request, 440 HttpServletResponse response) { 441 StringWriter msgBodyWriter = new StringWriter (); 442 PrintWriter strOut = new PrintWriter (msgBodyWriter); 443 strOut.println("Your Jahia Server has generated an error. Please review the details below for additional information: "); 444 if (t instanceof JahiaException) { 445 JahiaException nje = (JahiaException) t; 446 String severityMsg = "Undefined"; 447 switch (nje.getSeverity()) { 448 case JahiaException.WARNING_SEVERITY : severityMsg = "WARNING"; break; 449 case JahiaException.ERROR_SEVERITY : severityMsg = "ERROR"; break; 450 case JahiaException.CRITICAL_SEVERITY : severityMsg = "CRITICAL"; break; 451 case JahiaException.KISSYOURASSGOODBYE_SEVERITY : severityMsg = "FATAL"; break; 452 } 453 strOut.println("Severity : " + severityMsg); 454 } 455 strOut.println("Error : " + t.getMessage()); 456 457 if ((request != null) && (response != null)) { 458 strOut.println("URL : " + request.getRequestURL() + " Method : " + request.getMethod()); 459 strOut.println("Remote host : " + request.getRemoteHost() + " Remote Address : " + request.getRemoteAddr()); 460 strOut.println("Request headers : "); 461 Enumeration headerNames = request.getHeaderNames(); 462 while (headerNames.hasMoreElements()) { 463 String headerName = (String ) headerNames.nextElement(); 464 String headerValue = request.getHeader(headerName); 465 strOut.println(" " + headerName + ":" + headerValue); 466 } 467 } 468 strOut.println("Stack trace : "); 469 String stackTraceStr = stackTraceToString(t); 470 strOut.println(stackTraceStr); 471 strOut.println(""); 472 return msgBodyWriter.toString(); 473 } 474 475 487 public static String stackTraceToString(Throwable t) { 488 int nestingDepth = getNestedExceptionDepth(t, 0); 489 return recursiveStackTraceToString(t, nestingDepth); 490 } 491 492 private static String recursiveStackTraceToString(Throwable t, int curDepth) { 493 if (t == null) { 494 return ""; 495 } 496 StringWriter msgBodyWriter = new StringWriter (); 497 PrintWriter strOut = new PrintWriter (msgBodyWriter); 498 Throwable innerThrowable = null; 499 if (t instanceof ServletException ) { 500 ServletException se = (ServletException ) t; 501 innerThrowable = se.getRootCause(); 502 } else if (t instanceof JahiaException) { 503 JahiaException je = (JahiaException) t; 504 innerThrowable = je.getRootCause(); 505 } else if (t instanceof InvocationTargetException ) { 506 InvocationTargetException ite = (InvocationTargetException ) t; 507 innerThrowable = ite.getTargetException(); 508 } 509 if (innerThrowable != null) { 510 String innerExceptionTrace = recursiveStackTraceToString(innerThrowable, curDepth-1); 511 msgBodyWriter.write(innerExceptionTrace); 512 } 513 if (curDepth == 0) { 514 strOut.println("Cause level : " + curDepth + " (level 0 is the most precise exception)"); 515 516 } else { 517 strOut.println("Cause level : " + curDepth); 518 } 519 t.printStackTrace(strOut); 520 return msgBodyWriter.toString(); 521 } 522 523 public static int getNestedExceptionDepth(Throwable t, int curDepth) { 524 if (t == null) { 525 return curDepth; 526 } 527 int newDepth = curDepth; 528 Throwable innerThrowable = null; 529 if (t instanceof ServletException ) { 530 ServletException se = (ServletException ) t; 531 innerThrowable = se.getRootCause(); 532 } else if (t instanceof JahiaException) { 533 JahiaException je = (JahiaException) t; 534 innerThrowable = je.getRootCause(); 535 } else if (t instanceof InvocationTargetException ) { 536 InvocationTargetException ite = (InvocationTargetException ) t; 537 innerThrowable = ite.getTargetException(); 538 } 539 if (innerThrowable != null) { 540 newDepth = getNestedExceptionDepth(innerThrowable, curDepth+1); 541 } 542 return newDepth; 543 } 544 545 552 public static Throwable getNestedException(Throwable t) { 553 if (t == null) { 554 return null; 555 } 556 Throwable innerThrowable = null; 557 if (t instanceof ServletException ) { 558 ServletException se = (ServletException ) t; 559 innerThrowable = se.getRootCause(); 560 } else if (t instanceof JahiaException) { 561 JahiaException je = (JahiaException) t; 562 innerThrowable = je.getRootCause(); 563 } else if (t instanceof InvocationTargetException ) { 564 InvocationTargetException ite = (InvocationTargetException ) t; 565 innerThrowable = ite.getTargetException(); 566 } 567 if (innerThrowable != null) { 568 return getNestedException(innerThrowable); 569 } else { 570 return t; 571 } 572 } 573 } 574 | Popular Tags |