Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 173049 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/ui/internal/ide/IDEWorkbenchErrorHandler.java (-87 / +139 lines)
Lines 14-29 Link Here
14
import org.eclipse.core.runtime.IProgressMonitor;
14
import org.eclipse.core.runtime.IProgressMonitor;
15
import org.eclipse.core.runtime.IStatus;
15
import org.eclipse.core.runtime.IStatus;
16
import org.eclipse.core.runtime.Status;
16
import org.eclipse.core.runtime.Status;
17
import org.eclipse.jface.dialogs.IDialogConstants;
18
import org.eclipse.jface.dialogs.MessageDialog;
17
import org.eclipse.osgi.util.NLS;
19
import org.eclipse.osgi.util.NLS;
18
import org.eclipse.swt.SWT;
19
import org.eclipse.swt.SWTError;
20
import org.eclipse.swt.SWTError;
20
import org.eclipse.swt.widgets.MessageBox;
21
import org.eclipse.swt.graphics.Image;
21
import org.eclipse.swt.widgets.Shell;
22
import org.eclipse.swt.widgets.Shell;
22
import org.eclipse.ui.PlatformUI;
23
import org.eclipse.ui.PlatformUI;
23
import org.eclipse.ui.application.IWorkbenchConfigurer;
24
import org.eclipse.ui.application.IWorkbenchConfigurer;
24
import org.eclipse.ui.internal.ide.dialogs.InternalErrorDialog;
25
import org.eclipse.ui.internal.ide.dialogs.InternalErrorDialog;
26
import org.eclipse.ui.progress.IProgressConstants;
25
import org.eclipse.ui.progress.UIJob;
27
import org.eclipse.ui.progress.UIJob;
26
import org.eclipse.ui.statushandlers.StatusAdapter;
28
import org.eclipse.ui.statushandlers.StatusAdapter;
29
import org.eclipse.ui.statushandlers.StatusManager;
27
import org.eclipse.ui.statushandlers.WorkbenchErrorHandler;
30
import org.eclipse.ui.statushandlers.WorkbenchErrorHandler;
28
31
29
import com.ibm.icu.text.MessageFormat;
32
import com.ibm.icu.text.MessageFormat;
Lines 40-48 Link Here
40
43
41
	private int exceptionCount = 0;
44
	private int exceptionCount = 0;
42
45
43
	private InternalErrorDialog dialog;
46
	static private FatalErrorDialog dialog;
44
45
	private Shell defaultParent;
46
47
47
	private boolean closing = false;
48
	private boolean closing = false;
48
49
Lines 62-68 Link Here
62
63
63
	private static String MSG_FATAL_ERROR_Recursive = IDEWorkbenchMessages.FatalError_RecursiveError;
64
	private static String MSG_FATAL_ERROR_Recursive = IDEWorkbenchMessages.FatalError_RecursiveError;
64
65
65
	private static String MSG_FATAL_ERROR_RecursiveTitle = IDEWorkbenchMessages.Internal_error;
66
	private static String MSG_FATAL_ERROR_Title = IDEWorkbenchMessages.InternalError;
66
67
67
	/**
68
	/**
68
	 * @param configurer
69
	 * @param configurer
Lines 78-84 Link Here
78
	 *      int)
79
	 *      int)
79
	 */
80
	 */
80
	public void handle(final StatusAdapter statusAdapter, int style) {
81
	public void handle(final StatusAdapter statusAdapter, int style) {
81
		if (statusAdapter.getStatus().getException() != null) {
82
83
		// if fatal error occurs, we will show the blocking error dialog anyway
84
		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 fatal error occurs, we will ask to close the workbench
97
		if (isFatal(statusAdapter) && style != StatusManager.NONE) {
82
			UIJob handlingExceptionJob = new UIJob("IDE Exception Handler") //$NON-NLS-1$
98
			UIJob handlingExceptionJob = new UIJob("IDE Exception Handler") //$NON-NLS-1$
83
			{
99
			{
84
				/*
100
				/*
Lines 99-143 Link Here
99
			handlingExceptionJob.setSystem(true);
115
			handlingExceptionJob.setSystem(true);
100
			handlingExceptionJob.schedule();
116
			handlingExceptionJob.schedule();
101
		}
117
		}
102
103
		super.handle(statusAdapter, style);
104
	}
118
	}
105
119
106
	private Shell getParentShell() {
120
	private boolean isFatal(final StatusAdapter statusAdapter) {
107
		if (defaultParent == null) {
121
		if (statusAdapter.getStatus().getException() != null
108
			defaultParent = new Shell();
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;
109
		}
127
		}
110
128
		return false;
111
		return defaultParent;
112
	}
129
	}
113
130
114
	/**
131
	private void handleException(Throwable t) {
115
	 * Handles an event loop exception
116
	 * 
117
	 * @param t
118
	 *            the exception to handle
119
	 */
120
	public void handleException(Throwable t) {
121
		try {
132
		try {
122
			exceptionCount++;
133
			exceptionCount++;
123
			if (exceptionCount > 1) {
134
			if (exceptionCount > 1) {
124
				if (closing) {
135
				dialog.updateMessage(MessageFormat.format(MSG_FATAL_ERROR,
125
					return;
126
				}
127
				Shell parent = getParentShell();
128
				if (dialog != null && dialog.getShell() != null
129
						&& !dialog.getShell().isDisposed()) {
130
					parent = dialog.getShell();
131
				}
132
				MessageBox box = new MessageBox(parent, SWT.ICON_ERROR
133
						| SWT.YES | SWT.NO | SWT.SYSTEM_MODAL);
134
				box.setText(MSG_FATAL_ERROR_RecursiveTitle);
135
				box.setMessage(MessageFormat.format(MSG_FATAL_ERROR,
136
						new Object[] { MSG_FATAL_ERROR_Recursive }));
136
						new Object[] { MSG_FATAL_ERROR_Recursive }));
137
				int result = box.open();
137
				dialog.getShell().forceActive();
138
				if (result == SWT.YES) {
139
					closeWorkbench();
140
				}
141
			} else {
138
			} else {
142
				if (openQuestionDialog(t)) {
139
				if (openQuestionDialog(t)) {
143
					closeWorkbench();
140
					closeWorkbench();
Lines 149-155 Link Here
149
	}
146
	}
150
147
151
	/**
148
	/**
152
	 * Close the workbench and make sure all exceptions are handled.
149
	 * Informs the user about a fatal error. Returns true if the user decide to
150
	 * exit workbench or if another fatal error happens while reporting it.
151
	 */
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
			// Always open the dialog in case of major error but do not show the
173
			// detail button if not in debug mode.
174
			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
			// Workbench may be in such bad shape (no OS handles left, out of
187
			// memory, etc)
188
			// that is cannot show a message to the user. Just bail out now.
189
			System.err
190
					.println("Error while informing user about event loop exception:"); //$NON-NLS-1$
191
			t.printStackTrace();
192
			System.err.println("Dialog open exception:"); //$NON-NLS-1$
193
			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, // accept
211
				// the
212
				// default
213
				// window
214
				// icon
215
				message, detail, MessageDialog.QUESTION, labels, defaultIndex);
216
		if (detail != null) {
217
			dialog.setDetailButton(2);
218
		}
219
		return dialog;
220
	}
221
222
	/**
223
	 * Closes the workbench and make sure all exceptions are handled.
153
	 */
224
	 */
154
	private void closeWorkbench() {
225
	private void closeWorkbench() {
155
		if (closing) {
226
		if (closing) {
Lines 182-236 Link Here
182
		}
253
		}
183
	}
254
	}
184
255
185
	/**
256
	private class FatalErrorDialog extends InternalErrorDialog {
186
	 * Inform the user about a fatal error. Return true if the user decide to
257
187
	 * exit workbench or if another fatal error happens while reporting it.
258
		/**
188
	 */
259
		 * @param parentShell
189
	private boolean openQuestionDialog(Throwable internalError) {
260
		 * @param dialogTitle
190
		try {
261
		 * @param dialogTitleImage
191
			String msg = null;
262
		 * @param dialogMessage
192
			if (internalError instanceof OutOfMemoryError) {
263
		 * @param detail
193
				msg = MSG_OutOfMemoryError;
264
		 * @param dialogImageType
194
			} else if (internalError instanceof StackOverflowError) {
265
		 * @param dialogButtonLabels
195
				msg = MSG_StackOverflowError;
266
		 * @param defaultIndex
196
			} else if (internalError instanceof VirtualMachineError) {
267
		 */
197
				msg = MSG_VirtualMachineError;
268
		public FatalErrorDialog(Shell parentShell, String dialogTitle,
198
			} else if (internalError instanceof SWTError) {
269
				Image dialogTitleImage, String dialogMessage, Throwable detail,
199
				msg = MSG_SWTError;
270
				int dialogImageType, String[] dialogButtonLabels,
200
			} else {
271
				int defaultIndex) {
201
				if (internalError.getMessage() == null) {
272
			super(parentShell, dialogTitle, dialogTitleImage, dialogMessage,
202
					msg = IDEWorkbenchMessages.InternalErrorNoArg;
273
					detail, dialogImageType, dialogButtonLabels, defaultIndex);
203
				} else {
274
		}
204
					msg = NLS.bind(IDEWorkbenchMessages.InternalErrorOneArg,
275
205
							internalError.getMessage());
276
		/**
206
				}
277
		 * Updates the dialog message
207
				// if (Policy.DEBUG_OPEN_ERROR_DIALOG) {
278
		 * 
208
				// return openQuestion(null,
279
		 * @param message
209
				// IDEWorkbenchMessages.Internal_error, msg,
280
		 *            new message
210
				// internalError, 1);
281
		 */
211
				// }
282
		public void updateMessage(String message) {
212
				return false;
283
			this.message = message;
213
			}
284
			this.messageLabel.setText(message);
214
			// Always open the dialog in case of major error but do not show the
285
			this.messageLabel.update();
215
			// detail button if not in debug mode.
216
			Throwable detail = internalError;
217
			if (!Policy.DEBUG_OPEN_ERROR_DIALOG) {
218
				detail = null;
219
			}
220
			return InternalErrorDialog.openQuestion(PlatformUI.getWorkbench()
221
					.getActiveWorkbenchWindow().getShell(),
222
					IDEWorkbenchMessages.Internal_error, MessageFormat.format(
223
							MSG_FATAL_ERROR, new Object[] { msg }), detail, 1);
224
		} catch (Throwable th) {
225
			// Workbench may be in such bad shape (no OS handles left, out of
226
			// memory, etc)
227
			// that is cannot show a message to the user. Just bail out now.
228
			System.err
229
					.println("Error while informing user about event loop exception:"); //$NON-NLS-1$
230
			internalError.printStackTrace();
231
			System.err.println("Dialog open exception:"); //$NON-NLS-1$
232
			th.printStackTrace();
233
			return true;
234
		}
286
		}
235
	}
287
	}
236
}
288
}

Return to bug 173049