1 11 12 package org.eclipse.ui.internal.ide; 13 14 import org.eclipse.core.runtime.IProgressMonitor; 15 import org.eclipse.core.runtime.IStatus; 16 import org.eclipse.core.runtime.Status; 17 import org.eclipse.jface.dialogs.IDialogConstants; 18 import org.eclipse.jface.dialogs.MessageDialog; 19 import org.eclipse.osgi.util.NLS; 20 import org.eclipse.swt.SWTError; 21 import org.eclipse.swt.graphics.Image; 22 import org.eclipse.swt.widgets.Shell; 23 import org.eclipse.ui.PlatformUI; 24 import org.eclipse.ui.application.IWorkbenchConfigurer; 25 import org.eclipse.ui.internal.ide.dialogs.InternalErrorDialog; 26 import org.eclipse.ui.progress.IProgressConstants; 27 import org.eclipse.ui.progress.UIJob; 28 import org.eclipse.ui.statushandlers.StatusAdapter; 29 import org.eclipse.ui.statushandlers.StatusManager; 30 import org.eclipse.ui.statushandlers.WorkbenchErrorHandler; 31 32 import com.ibm.icu.text.MessageFormat; 33 34 42 public class IDEWorkbenchErrorHandler extends WorkbenchErrorHandler { 43 44 private int exceptionCount = 0; 45 46 static private FatalErrorDialog dialog; 47 48 private boolean closing = false; 49 50 private IWorkbenchConfigurer workbenchConfigurer; 51 52 private static String MSG_OutOfMemoryError = IDEWorkbenchMessages.FatalError_OutOfMemoryError; 55 56 private static String MSG_StackOverflowError = IDEWorkbenchMessages.FatalError_StackOverflowError; 57 58 private static String MSG_VirtualMachineError = IDEWorkbenchMessages.FatalError_VirtualMachineError; 59 60 private static String MSG_SWTError = IDEWorkbenchMessages.FatalError_SWTError; 61 62 private static String MSG_FATAL_ERROR = IDEWorkbenchMessages.FatalError; 63 64 private static String MSG_FATAL_ERROR_Recursive = IDEWorkbenchMessages.FatalError_RecursiveError; 65 66 private static String MSG_FATAL_ERROR_Title = IDEWorkbenchMessages.InternalError; 67 68 71 public IDEWorkbenchErrorHandler(IWorkbenchConfigurer configurer) { 72 workbenchConfigurer = configurer; 73 } 74 75 81 public void handle(final StatusAdapter statusAdapter, int style) { 82 83 if (isFatal(statusAdapter)) { 85 if (statusAdapter 86 .getProperty(IProgressConstants.NO_IMMEDIATE_ERROR_PROMPT_PROPERTY) == Boolean.TRUE) { 87 statusAdapter.setProperty( 88 IProgressConstants.NO_IMMEDIATE_ERROR_PROMPT_PROPERTY, 89 Boolean.FALSE); 90 } 91 super.handle(statusAdapter, style | StatusManager.BLOCK); 92 } else { 93 super.handle(statusAdapter, style); 94 } 95 96 if (isFatal(statusAdapter) && style != StatusManager.NONE) { 98 UIJob handlingExceptionJob = new UIJob("IDE Exception Handler") { 100 105 public IStatus runInUIThread(IProgressMonitor monitor) { 106 handleException(statusAdapter.getStatus().getException()); 107 return new Status( 108 IStatus.OK, 109 IDEWorkbenchPlugin.IDE_WORKBENCH, 110 IDEWorkbenchMessages.IDEExceptionHandler_ExceptionHandledMessage); 111 } 112 113 }; 114 115 handlingExceptionJob.setSystem(true); 116 handlingExceptionJob.schedule(); 117 } 118 } 119 120 private boolean isFatal(final StatusAdapter statusAdapter) { 121 if (statusAdapter.getStatus().getException() != null 122 && (statusAdapter.getStatus().getException() instanceof OutOfMemoryError 123 || statusAdapter.getStatus().getException() instanceof StackOverflowError 124 || statusAdapter.getStatus().getException() instanceof VirtualMachineError || statusAdapter 125 .getStatus().getException() instanceof SWTError)) { 126 return true; 127 } 128 return false; 129 } 130 131 private void handleException(Throwable t) { 132 try { 133 exceptionCount++; 134 if (exceptionCount > 1) { 135 dialog.updateMessage(MessageFormat.format(MSG_FATAL_ERROR, 136 new Object [] { MSG_FATAL_ERROR_Recursive })); 137 dialog.getShell().forceActive(); 138 } else { 139 if (openQuestionDialog(t)) { 140 closeWorkbench(); 141 } 142 } 143 } finally { 144 exceptionCount--; 145 } 146 } 147 148 152 private boolean openQuestionDialog(Throwable t) { 153 try { 154 String msg = null; 155 if (t instanceof OutOfMemoryError ) { 156 msg = MSG_OutOfMemoryError; 157 } else if (t instanceof StackOverflowError ) { 158 msg = MSG_StackOverflowError; 159 } else if (t instanceof VirtualMachineError ) { 160 msg = MSG_VirtualMachineError; 161 } else if (t instanceof SWTError) { 162 msg = MSG_SWTError; 163 } else { 164 if (t.getMessage() == null) { 165 msg = IDEWorkbenchMessages.InternalErrorNoArg; 166 } else { 167 msg = NLS.bind(IDEWorkbenchMessages.InternalErrorOneArg, t 168 .getMessage()); 169 } 170 } 171 172 Throwable detail = t; 175 if (!Policy.DEBUG_OPEN_ERROR_DIALOG) { 176 detail = null; 177 } 178 179 dialog = openInternalQuestionDialog(PlatformUI.getWorkbench() 180 .getActiveWorkbenchWindow().getShell(), 181 MSG_FATAL_ERROR_Title, MessageFormat.format( 182 MSG_FATAL_ERROR, new Object [] { msg }), detail, 1); 183 184 return dialog.open() == 0; 185 } catch (Throwable th) { 186 System.err 190 .println("Error while informing user about event loop exception:"); t.printStackTrace(); 192 System.err.println("Dialog open exception:"); th.printStackTrace(); 194 return true; 195 } 196 } 197 198 private FatalErrorDialog openInternalQuestionDialog(Shell parent, 199 String title, String message, Throwable detail, int defaultIndex) { 200 String [] labels; 201 if (detail == null) { 202 labels = new String [] { IDialogConstants.YES_LABEL, 203 IDialogConstants.NO_LABEL }; 204 } else { 205 labels = new String [] { IDialogConstants.YES_LABEL, 206 IDialogConstants.NO_LABEL, 207 IDialogConstants.SHOW_DETAILS_LABEL }; 208 } 209 210 FatalErrorDialog dialog = new FatalErrorDialog(parent, title, null, message, detail, MessageDialog.QUESTION, labels, defaultIndex); 216 if (detail != null) { 217 dialog.setDetailButton(2); 218 } 219 return dialog; 220 } 221 222 225 private void closeWorkbench() { 226 if (closing) { 227 return; 228 } 229 230 try { 231 closing = true; 232 if (dialog != null && dialog.getShell() != null 233 && !dialog.getShell().isDisposed()) { 234 dialog.close(); 235 } 236 workbenchConfigurer.emergencyClose(); 237 } catch (RuntimeException re) { 238 System.err 242 .println("Fatal runtime error happened during workbench emergency close."); re.printStackTrace(); 244 throw re; 245 } catch (Error e) { 246 System.err 250 .println("Fatal error happened during workbench emergency close."); e.printStackTrace(); 252 throw e; 253 } 254 } 255 256 private class FatalErrorDialog extends InternalErrorDialog { 257 258 268 public FatalErrorDialog(Shell parentShell, String dialogTitle, 269 Image dialogTitleImage, String dialogMessage, Throwable detail, 270 int dialogImageType, String [] dialogButtonLabels, 271 int defaultIndex) { 272 super(parentShell, dialogTitle, dialogTitleImage, dialogMessage, 273 detail, dialogImageType, dialogButtonLabels, defaultIndex); 274 } 275 276 282 public void updateMessage(String message) { 283 this.message = message; 284 this.messageLabel.setText(message); 285 this.messageLabel.update(); 286 } 287 } 288 } 289 | Popular Tags |