org.eclipse.swt.internal.ExceptionStash Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.eclipse.swt.gtk.linux.ppc64le Show documentation
Show all versions of org.eclipse.swt.gtk.linux.ppc64le Show documentation
Standard Widget Toolkit for GTK on ppc64le
The newest version!
/*******************************************************************************
* Copyright (c) 2021, 2023 Syntevo and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Syntevo - initial API and implementation
*******************************************************************************/
package org.eclipse.swt.internal;
import org.eclipse.swt.widgets.Display;
/**
* The intent of this class is to insulate SWT from exceptions occurring in
* user's listeners, so that SWT remains stable and does not accidentally
* crash JVM or enter some very broken state. The supposed use is:
*
* void someSwtInternalFunction() {
* // Make a stash to collect all exceptions from user listeners
* try (ExceptionStash exceptions = new ExceptionStash ()) {
* // Perform some action that may call a throwing user's listener
* try {
* sendEvent(SWT.SomeEvent);
* } catch (Error | RuntimeException ex) {
* exceptions.stash (ex);
* }
*
* // Do some important SWT stuff that you would normally do in
* // 'finally' clause. With 'ExceptionStash' you can interleave
* // important things with listeners without making code ugly.
* MakeSureThingsDontBreak();
*
* // Perform another action that may call a throwing user's listener.
* // Done in an independent 'try' block to make sure that all events
* // are sent regardless of exceptions in some of the listeners.
* try {
* askWidgetToSendMoreEvents();
* } catch (Error | RuntimeException ex) {
* exceptions.stash (ex);
* }
*
* // Exiting from 'try' statement will close ExceptionStash and
* // re-throw collected exception. If there are multiple exceptions,
* // all subsequent ones will be added as 'Throwable.addSuppressed()'.
* }
* }
*/
public class ExceptionStash implements AutoCloseable {
Throwable storedThrowable;
public void stash(Throwable throwable) {
/* First, try to pass it to the global handler */
try {
Display display = Display.getCurrent ();
if (display != null) {
if (throwable instanceof RuntimeException runtimeEx) {
display.getRuntimeExceptionHandler().accept(runtimeEx);
/* If handler doesn't throw then the exception is fully handled */
return;
} else if (throwable instanceof Error er) {
display.getErrorHandler().accept(er);
/* If handler doesn't throw then the exception is fully handled */
return;
}
}
} catch (Throwable ex) {
/* Handler may have thrown something new */
throwable = ex;
}
/* No handler or it also thrown */
if (storedThrowable != null) {
storedThrowable.addSuppressed(throwable);
} else {
storedThrowable = throwable;
}
}
public void close() {
if (storedThrowable == null) return;
Throwable throwable = storedThrowable;
storedThrowable = null;
if (throwable instanceof RuntimeException runtimeEx) {
throw runtimeEx;
} else if (throwable instanceof Error er) {
throw er;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy