Skip to content

Commit

Permalink
Initialize cause of some InterruptedExceptions
Browse files Browse the repository at this point in the history
Pack an OperationCanceledException inside the InterruptedException when
this is thrown due to the user canceling an operation. This makes it
easier to determine the cause of the InterruptedException from outside
the methods (i.e. in the catch-clauses). Adapt the method
ModalContext::checkCanceled accordingly. Change
WorkspaceModifyOperation::run so it preserves the original
exceptions if possible.

Same idea as
#1259
  • Loading branch information
fedejeanne authored and HeikoKlare committed Nov 17, 2023
1 parent b72dc9b commit 0f77e30
Showing 1 changed file with 14 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package org.eclipse.ui.actions;

import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.atomic.AtomicReference;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRunnable;
Expand Down Expand Up @@ -103,20 +104,19 @@ protected abstract void execute(IProgressMonitor monitor)
@Override
public synchronized final void run(IProgressMonitor monitor)
throws InvocationTargetException, InterruptedException {
final InvocationTargetException[] iteHolder = new InvocationTargetException[1];
AtomicReference<InvocationTargetException> rethrownInvocationTargetException = new AtomicReference<>();
AtomicReference<InterruptedException> rethrownInterruptedException = new AtomicReference<>();
try {
IWorkspaceRunnable workspaceRunnable = pm -> {
try {
execute(pm);
} catch (InvocationTargetException e1) {
// Pass it outside the workspace runnable
iteHolder[0] = e1;
rethrownInvocationTargetException.set(e1);
} catch (InterruptedException e2) {
// Re-throw as OperationCanceledException, which will be
// caught and re-thrown as InterruptedException below.
throw new OperationCanceledException(e2.getMessage());
rethrownInterruptedException.set(e2);
}
// CoreException and OperationCanceledException are propagated
// CoreException and unchecked exceptions (e.g. OperationCanceledException) are
// propagated to the outer catch
};
// if we are in the UI thread, make sure we use progress monitor
// that spins event loop to allow processing of pending asyncExecs
Expand All @@ -137,9 +137,13 @@ public synchronized final void run(IProgressMonitor monitor)
interruptedException.initCause(e);
throw interruptedException;
}
// Re-throw the InvocationTargetException, if any occurred
if (iteHolder[0] != null) {
throw iteHolder[0];

// Re-throw any exceptions caught while running the IWorkspaceRunnable
if (rethrownInvocationTargetException.get() != null) {
throw rethrownInvocationTargetException.get();
}
if (rethrownInterruptedException.get() != null) {
throw rethrownInterruptedException.get();
}
}
@Override
Expand Down

0 comments on commit 0f77e30

Please sign in to comment.