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    }