private void run() {

			Runnable swingExceptionCatcher = () -> {
				try {
					delegateCallback.call();
				}
				catch (Throwable t) {
					exception = t;
				}
			};

			try {
				doRun(swingExceptionCatcher);
			}
			catch (InterruptedException e) {
				// Typically, this InterrruptedException that is caused by our test harness when it
				// is interrupting the test thread after a previous Swing exception that we have
				// detected--we don't care to throw the InterruptedException, as we caused it.
				// Log a message to signal that unusual things may happen when in this state.
				Msg.debug(this, "\n>>>>>>>>>>>>>>>> Test thread interrupted.  Unusual/unexpected " +
					"errors may follow.\n\n");
			}
			catch (InvocationTargetException e) {
				// Assume that if we have an exception reported by our catcher above, then that is
				// the root cause of this exception and do not report this one.   This should not
				// happen, as we are catching the exception above.
			}
		}
Call this version of {@link #runSwing(Runnable)} when you expect your runnable <b>may</b>
throw exceptions

@param callback the runnable code snippet to call
@throws Exception any exception that is thrown on the Swing thread
Ghidra/Framework/Gui/src/main/java/generic/test/AbstractGuiTest.java