1 64 65 package com.jcorporate.expresso.services.controller; 66 67 import com.jcorporate.expresso.core.controller.ControllerException; 68 import com.jcorporate.expresso.core.controller.ControllerRequest; 69 import com.jcorporate.expresso.core.controller.ControllerResponse; 70 import com.jcorporate.expresso.core.controller.DBController; 71 import com.jcorporate.expresso.core.controller.NonHandleableException; 72 import com.jcorporate.expresso.core.controller.Output; 73 import com.jcorporate.expresso.core.controller.State; 74 import com.jcorporate.expresso.core.db.DBException; 75 import com.jcorporate.expresso.core.dbobj.SecuredDBObject; 76 import com.jcorporate.expresso.core.misc.ConfigManager; 77 import com.jcorporate.expresso.core.misc.ConfigurationException; 78 import com.jcorporate.expresso.core.misc.DateTime; 79 import com.jcorporate.expresso.core.misc.EMailSender; 80 import com.jcorporate.expresso.core.misc.EventHandler; 81 import com.jcorporate.expresso.core.misc.SerializableString; 82 import com.jcorporate.expresso.core.misc.StringUtil; 83 import com.jcorporate.expresso.core.security.User; 84 import com.jcorporate.expresso.kernel.exception.ChainedException; 85 import com.jcorporate.expresso.services.dbobj.DBMessage; 86 import com.jcorporate.expresso.services.dbobj.Setup; 87 import org.apache.log4j.Logger; 88 89 import java.io.ByteArrayOutputStream ; 90 import java.io.PrintStream ; 91 import java.util.Iterator ; 92 import java.util.StringTokenizer ; 93 94 95 101 public class ErrorHandler 102 extends DBController { 103 private static Logger log = Logger.getLogger(ErrorHandler.class); 104 105 108 public ErrorHandler() { 109 super(); 110 State handle = new State("handle", "Handle an Error"); 111 addState(handle); 112 setInitialState("handle"); 113 this.setSchema(com.jcorporate.expresso.core.ExpressoSchema.class); 114 } 115 116 117 private String getAttribString(String key, ControllerRequest params) 118 throws NonHandleableException { 119 StringUtil.assertNotBlank(key, 120 "Cannot request a blank or null key here"); 121 122 Object o = null; 123 124 try { 125 o = params.getSession().getPersistentAttribute(key); 126 } catch (ControllerException ce) { 127 throw new NonHandleableException(ce); 128 } 129 if (o == null) { 130 return null; 131 } 132 if (o instanceof SerializableString) { 133 SerializableString s = (SerializableString) o; 134 135 return StringUtil.notNull(s.toString()); 136 } 137 138 throw new NonHandleableException("Value in session key '" + key + 139 "' " + 140 "was not a SerializableString - it was '" + 141 o.getClass().getName() + "'"); 142 } 143 144 private void handleState(ControllerResponse myResponse, 145 ControllerRequest params) 146 throws ControllerException, NonHandleableException { 147 log.debug("Handling error begins"); 148 149 Throwable t = null; 150 String callerType = ""; 151 152 try { 153 log.debug("Getting caller type"); 154 callerType = StringUtil.notNull(getAttribString("callerType", 155 params)); 156 log.debug("Getting exception"); 157 158 Object o = params.getSession().getPersistentAttribute("exception"); 159 160 if (o == null) { 161 throw new NonHandleableException("No error in session"); 162 } 163 if (o instanceof Throwable ) { 164 t = (Throwable ) o; 165 } else { 166 throw new NonHandleableException("The 'exception' object in the " + 167 "session was not a 'Throwable'. It was '" + 168 o.getClass().getName() + "'"); 169 } 170 if (t == null) { 171 throw new NonHandleableException("There was no attribute called " + 172 "'exception' stored in the current session. Unable to handle error"); 173 } 174 175 176 boolean showStack = true; 177 178 try { 179 showStack = ConfigManager.getContext(params.getDataContext()).showStackTrace(); 180 } catch (ConfigurationException ce) { 181 throw new NonHandleableException(ce); 182 } 183 if (showStack) { 184 if (t != null) { 185 ByteArrayOutputStream bos = new ByteArrayOutputStream (); 186 t.printStackTrace(new PrintStream (bos)); 187 myResponse.addOutput(new Output("stackTrace", 188 bos.toString())); 189 } else { 190 myResponse.addOutput(new Output("stackTrace", 191 "No stack trace was available")); 192 } 193 } else { 194 myResponse.addOutput(new Output("stackTrace", 195 "Stack trace display is not " + "enabled. To enable, add 'stackTrace=y' to the '" + 196 params.getDataContext() + 197 ".properties' file")); 198 } 199 200 myResponse.addOutput(new Output("exceptionMessage", t.getMessage())); 201 202 if (t instanceof ChainedException) { 203 ChainedException c = (ChainedException) t; 204 Throwable nestedException = c.getNested(); 205 206 if (nestedException != null) { 207 myResponse.addOutput(new Output("nestedMessage", 208 StringUtil.notNull(c.getNested().getMessage()))); 209 } else { 210 myResponse.addOutput(new Output("nestedMessage", "")); 211 } 212 } else { 213 myResponse.addOutput(new Output("nestedMessage", "")); 214 } 215 } catch (Exception ex) { 216 log.error("Exception thrown after getting:", ex); 217 throw new NonHandleableException("Unable to handle exception", ex); 218 } 219 220 reportError(t, myResponse, params); 221 222 if (t instanceof SecurityException ) { 223 displaySecurityException(myResponse, params); 224 } else if (t instanceof DBException) { 225 displayDBException((DBException) t, myResponse, params); 226 } else { 227 displayOtherException(myResponse, params); 228 } 229 if (callerType.equals("job")) { 230 try { 231 User u = new User(); 232 u.setDataContext(params.getDataContext()); 233 u.setLoginName(params.getUser()); 234 235 StringBuffer bigString = new StringBuffer (getAttribString("message", 236 params)); 237 bigString.append("\n"); 238 239 String dbDescrip = StringUtil.notNull( 240 ConfigManager.getContext(params.getDataContext()).getDescription()); 241 242 if (!dbDescrip.equals("")) { 243 dbDescrip = " (" + dbDescrip + ") "; 244 } 245 246 bigString.append("A " + t.getClass().getName() + 247 "Error occurred in db/context '" + 248 params.getDataContext() + "' " + dbDescrip + "\n"); 249 bigString.append("Server:" + 250 Setup.getValueRequired(params.getDataContext(), 251 "HTTPServ") + "\n"); 252 bigString.append("Stack Trace:\n"); 253 bigString.append(myResponse.getOutput("stackTrace").getContent()); 254 255 if (u.find()) { 256 String oneRecipient = u.getEmail(); 257 258 if (log.isDebugEnabled()) { 259 log.debug("Notifying '" + oneRecipient + 260 "' of failure of " + "job"); 261 } 262 263 EMailSender ems = new EMailSender(); 264 ems.setDBName(params.getDataContext()); 265 ems.send(oneRecipient, getAttribString("message", params), 266 bigString.toString()); 267 } 268 } catch (Exception ie) { 269 log.warn("Error sending mail", ie); 270 } 271 } 272 } 273 274 275 283 private void displaySecurityException(ControllerResponse myResponse, 284 ControllerRequest params) 285 throws NonHandleableException { 286 log.debug("Displaying security exception"); 287 288 try { 289 myResponse.addOutput(new Output("errorType", "security")); 290 displayException(myResponse, params); 291 } catch (ControllerException ce) { 292 throw new NonHandleableException(ce); 293 } 294 } 295 296 297 306 private void displayDBException(DBException de, 307 ControllerResponse myResponse, 308 ControllerRequest params) 309 throws NonHandleableException { 310 log.debug("Displaying db exception"); 311 312 try { 313 myResponse.addOutput(new Output("errorType", "db")); 314 315 316 genOutputErrorBody(getAttribString("message", params), myResponse); 317 genOutputErrorBodyDB(de.getDBMessage(), myResponse); 318 } catch (ControllerException ce) { 319 throw new NonHandleableException(ce); 320 } 321 } 322 323 324 333 private void displayOtherException(ControllerResponse myResponse, 334 ControllerRequest params) 335 throws NonHandleableException { 336 log.debug("Displaying other exception"); 337 338 try { 339 myResponse.addOutput(new Output("errorType", "other")); 340 displayException(myResponse, params); 341 } catch (ControllerException ce) { 342 throw new NonHandleableException(ce); 343 } 344 } 345 346 347 355 private void displayException(ControllerResponse myResponse, 356 ControllerRequest params) 357 throws NonHandleableException { 358 try { 359 360 361 genOutputErrorBody(getAttribString("message", params), myResponse); 362 } catch (ControllerException ce) { 363 throw new NonHandleableException(ce); 364 } 365 } 366 367 368 373 public String getTitle() { 374 return ("Error Handling"); 375 } 376 377 386 public ControllerResponse newState(String newState, 387 ControllerRequest params) 388 throws ControllerException, 389 NonHandleableException { 390 newState = "handle"; 391 392 ControllerResponse myResponse = null; 393 394 try { 395 myResponse = super.newState(newState, params); 396 handleState(myResponse, params); 397 } catch (Exception ee) { 398 throw new NonHandleableException(ee); 399 } 400 401 log.debug("Error controller returning from newstate"); 402 403 return myResponse; 404 } 405 406 407 416 public synchronized boolean stateAllowed(String newState, 417 ControllerRequest params) 418 throws ControllerException { 419 return true; 420 } 421 422 423 432 protected void reportError(Throwable t, ControllerResponse myResponse, 433 ControllerRequest params) 434 throws NonHandleableException { 435 try { 436 StringBuffer theMessage = new StringBuffer (); 437 theMessage.append("Error:\n"); 438 theMessage.append("\tA " + t.getClass().getName() + 439 " Error occurred at " + 440 DateTime.getDateTimeForDB(params.getDataContext()) + 441 " in database/context '" + params.getDataContext() + 442 "' to user '" + params.getUser() + "'\n"); 443 theMessage.append("\tThe requested URL was '" + 444 getAttribString("RequestedURL", params) + "'\n"); 445 446 if (getAttribString("QueryString", params) != null) { 447 theMessage.append("?" + 448 getAttribString("QueryString", params) + 449 "'\n"); 450 } 451 452 String errorMessage = getAttribString("message", params); 453 454 if (errorMessage != null) { 455 theMessage.append("\t" + errorMessage); 456 } else { 457 theMessage.append("No error message was available"); 458 } 459 460 theMessage.append(myResponse.getOutput("stackTrace").getContent()); 461 log.error(theMessage.toString(), t); 462 463 try { 464 String servletEventFlag = StringUtil.notNull(Setup.getValue(params.getDataContext(), 465 "ServletEvent")); 466 467 if (servletEventFlag.equalsIgnoreCase("Y")) { 468 EventHandler.Event(params.getDataContext(), "SYSERROR", 469 theMessage.toString(), false); 470 } else if (servletEventFlag.equalsIgnoreCase("E")) { 471 if (!(t instanceof SecurityException )) { 472 EventHandler.Event(params.getDataContext(), "SYSERROR", 473 theMessage.toString(), false); 474 } 475 } else { 476 log.warn("Sending of errors via email is not enabled in " + 477 "db/context '" + params.getDataContext() + "'"); 478 } 479 } catch (Exception e) { 480 log.error("Unable to log error correctly:" + 481 theMessage.toString(), e); 482 } 483 } catch (DBException dbe) { 484 throw new NonHandleableException(dbe); 485 } catch (ControllerException ce) { 486 throw new NonHandleableException(ce); 487 } 488 } 489 490 491 500 private void genOutputErrorBody(String errorMessage, 501 ControllerResponse myResponse) 502 throws ControllerException { 503 if (errorMessage == null) { 504 log.error("Error message was null"); 505 errorMessage = ("Error message was null"); 506 } 507 508 myResponse.addOutput(new Output("originalError", errorMessage)); 509 510 StringTokenizer stk = new StringTokenizer (errorMessage, ":"); 511 String objectName = null; 512 513 if (stk.hasMoreTokens()) { 514 objectName = stk.nextToken(); 515 } else { 516 objectName = ("NONE"); 517 } 518 519 String message = (""); 520 String errorText = (""); 521 String messageNumber = (""); 522 523 if (stk.hasMoreTokens()) { 524 while (stk.hasMoreTokens()) { 525 message = message + stk.nextToken() + " "; 526 } 527 if (message.startsWith("[")) { 528 529 530 StringTokenizer stk2 = new StringTokenizer (message, "]"); 531 messageNumber = stk2.nextToken().substring(1); 532 533 while (stk2.hasMoreTokens()) { 534 errorText = errorText + stk2.nextToken(); 535 } 536 } else { 537 errorText = message; 538 messageNumber = ("None Assigned"); 539 } 540 } else { 541 errorText = errorMessage; 542 objectName = ("Unknown"); 543 messageNumber = ("None Assigned"); 544 } 545 546 myResponse.addOutput(new Output("errorText", errorText)); 547 myResponse.addOutput(new Output("messageNumber", messageNumber)); 548 myResponse.addOutput(new Output("objectName", objectName)); 549 } 550 551 552 protected void genOutputErrorBodyDB(String dbErrorMessage, 553 ControllerResponse myResponse) 554 throws ControllerException { 555 String newMessage = dbErrorMessage; 556 557 try { 558 if (!StringUtil.notNull(dbErrorMessage).equals("")) { 559 DBMessage dm = new DBMessage(SecuredDBObject.SYSTEM_ACCOUNT); 560 DBMessage oneDm = null; 561 562 for (Iterator dml = dm.searchAndRetrieveList().iterator(); 563 dml.hasNext();) { 564 oneDm = (DBMessage) dml.next(); 565 566 if (dbErrorMessage.indexOf(oneDm.getField("InputString")) != -1) { 567 newMessage = oneDm.getField("OutputString"); 568 break; 569 } 570 } 571 572 } 573 574 myResponse.addOutput(new Output("dbErrorMessage", newMessage)); 575 } catch (DBException de) { 576 log.error("Unable to lookup error message mappings", de); 577 } 578 } 579 580 } 581 | Popular Tags |