001 /** 002 * Copyright 2010 The Kuali Foundation Licensed under the 003 * Educational Community License, Version 2.0 (the "License"); you may 004 * not use this file except in compliance with the License. You may 005 * obtain a copy of the License at 006 * 007 * http://www.osedu.org/licenses/ECL-2.0 008 * 009 * Unless required by applicable law or agreed to in writing, 010 * software distributed under the License is distributed on an "AS IS" 011 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 012 * or implied. See the License for the specific language governing 013 * permissions and limitations under the License. 014 */ 015 016 package org.kuali.student.common.ui.client.widgets; 017 018 019 import org.kuali.student.common.ui.client.application.Application; 020 import org.kuali.student.common.ui.client.application.ApplicationContext; 021 import org.kuali.student.common.ui.client.logging.Logger; 022 import org.kuali.student.common.ui.client.mvc.Callback; 023 import org.kuali.student.common.ui.client.widgets.buttongroups.OkGroup; 024 import org.kuali.student.common.ui.client.widgets.buttongroups.ButtonEnumerations.OkEnum; 025 026 import com.google.gwt.core.client.GWT; 027 import com.google.gwt.user.client.Command; 028 import com.google.gwt.user.client.DeferredCommand; 029 import com.google.gwt.user.client.ui.SimplePanel; 030 import com.google.gwt.user.client.ui.VerticalPanel; 031 032 public class KSErrorDialog { 033 034 final static ApplicationContext context = Application.getApplicationContext(); 035 036 public enum MessagesRequired { 037 DIALOG_TITLE("errorDialogTitle"), 038 DESCRIBE_ACTION("describeAction"), 039 ERROR_DESCRIPTION("errorDescription"); 040 041 private String messageId; 042 private MessagesRequired(String messageId) { 043 this.messageId = messageId; 044 } 045 public String toString() { 046 return this.messageId; 047 } 048 } 049 050 public static void bindUncaughtExceptionHandler() { 051 GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() { 052 public void onUncaughtException(Throwable e) { 053 GWT.log(e.getMessage(), e); 054 //Window.alert("Uncaught exception was thrown:"+getStackTrace(e)+"\nMessage:"+e.getMessage()); 055 KSErrorDialog.show(e); 056 } 057 }); 058 } 059 060 private static String getStackTrace(Throwable t){ 061 StringBuilder sb = new StringBuilder(); 062 appendStackTrace(t,sb); 063 return sb.toString(); 064 } 065 066 private static void appendStackTrace(Throwable t, StringBuilder s) { 067 s.append(t.toString()); 068 s.append(": at\n"); 069 StackTraceElement[] stack = t.getStackTrace(); 070 for (StackTraceElement frame : stack) { 071 s.append(frame.toString()); 072 s.append("\n"); 073 } 074 } 075 076 public static void show(final Throwable error) { 077 final KSLightBox lightbox = new KSLightBox(); 078 079 final VerticalPanel panel = new VerticalPanel(); 080 panel.addStyleName("KS-Error-Dialog"); 081 082 final KSLabel title = new KSLabel(context.getMessage(MessagesRequired.DIALOG_TITLE.toString())); 083 title.addStyleName("KS-Error-Dialog-Title"); 084 085 final KSLabel errorDescriptionLabel = new KSLabel(context.getMessage(MessagesRequired.ERROR_DESCRIPTION.toString())); 086 errorDescriptionLabel.addStyleName("KS-Error-Dialog-Label"); 087 088 final SimplePanel errorDescriptionPanel = new SimplePanel(); 089 errorDescriptionPanel.addStyleName("KS-Error-Dialog-Panel"); 090 091 final KSTextArea errorDescription = new KSTextArea(); 092 errorDescription.setText(getErrorDescription(error)); 093 errorDescription.addStyleName("KS-Error-Dialog-TextArea"); 094 errorDescription.setReadOnly(true); 095 //errorDescription.setEnabled(false); 096 errorDescriptionPanel.add(errorDescription); 097 098 /* final KSLabel describeActionLabel = new KSLabel(context.getMessage(MessagesRequired.DESCRIBE_ACTION.toString())); 099 describeActionLabel.addStyleName(KSStyles.KS_ERROR_DIALOG_LABEL); 100 101 final SimplePanel actionDescriptionPanel = new SimplePanel(); 102 actionDescriptionPanel.addStyleName(KSStyles.KS_ERROR_DIALOG_PANEL); 103 104 final KSTextArea actionDescription = new KSTextArea(); 105 actionDescription.addStyleName(KSStyles.KS_ERROR_DIALOG_TEXTAREA); 106 actionDescriptionPanel.add(actionDescription); 107 */ 108 final OkGroup buttonPanel = new OkGroup(new Callback<OkEnum>(){ 109 110 @Override 111 public void exec(OkEnum result) { 112 switch(result){ 113 case Ok: 114 DeferredCommand.addCommand(new Command() { 115 public void execute() { 116 sendReport(error/*, actionDescription.getText()*/); 117 lightbox.hide(); 118 } 119 }); 120 break; 121 } 122 } 123 }); 124 125 lightbox.setNonCaptionHeader(title); 126 panel.add(errorDescriptionLabel); 127 panel.add(errorDescriptionPanel); 128 // panel.add(describeActionLabel); 129 // panel.add(actionDescriptionPanel); 130 panel.add(buttonPanel); 131 132 panel.setSize("100", "100"); 133 134 lightbox.setWidget(panel); 135 lightbox.setSize(440, 200); 136 lightbox.show(); 137 138 } 139 140 private static String getErrorDescription(Throwable error) { 141 // TODO maybe retrieve more error info 142 return error.getMessage(); 143 } 144 145 private static void sendReport(final Throwable error/*, final String actionDescription*/) { 146 // TODO actually gather client context info, such as browser version, user id, etc 147 Logger.getClientContextInfo().put("logType", "clientError"); 148 // Logger.getClientContextInfo().put("actionDescription", actionDescription); 149 Logger.error("Uncaught exception", error); 150 Logger.sendLogs(); 151 152 // hack, clear out context info, should probably find a better way of doing this 153 Logger.getClientContextInfo().clear(); 154 } 155 156 }