Skip to content

Commit 0d2fb70

Browse files
committed
Initialize cause of some InterruptedExceptions
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 eclipse-platform#1259
1 parent 2670545 commit 0d2fb70

File tree

1 file changed

+14
-10
lines changed

1 file changed

+14
-10
lines changed

bundles/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/WorkspaceModifyOperation.java

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package org.eclipse.ui.actions;
1515

1616
import java.lang.reflect.InvocationTargetException;
17+
import java.util.concurrent.atomic.AtomicReference;
1718

1819
import org.eclipse.core.resources.IResource;
1920
import org.eclipse.core.resources.IWorkspaceRunnable;
@@ -103,20 +104,19 @@ protected abstract void execute(IProgressMonitor monitor)
103104
@Override
104105
public synchronized final void run(IProgressMonitor monitor)
105106
throws InvocationTargetException, InterruptedException {
106-
final InvocationTargetException[] iteHolder = new InvocationTargetException[1];
107+
AtomicReference<InvocationTargetException> rethrownInvocationTargetException = new AtomicReference<>();
108+
AtomicReference<InterruptedException> rethrownInterruptedException = new AtomicReference<>();
107109
try {
108110
IWorkspaceRunnable workspaceRunnable = pm -> {
109111
try {
110112
execute(pm);
111113
} catch (InvocationTargetException e1) {
112-
// Pass it outside the workspace runnable
113-
iteHolder[0] = e1;
114+
rethrownInvocationTargetException.set(e1);
114115
} catch (InterruptedException e2) {
115-
// Re-throw as OperationCanceledException, which will be
116-
// caught and re-thrown as InterruptedException below.
117-
throw new OperationCanceledException(e2.getMessage());
116+
rethrownInterruptedException.set(e2);
118117
}
119-
// CoreException and OperationCanceledException are propagated
118+
// CoreException and unchecked exceptions (e.g. OperationCanceledException) are
119+
// propagated to the outer catch
120120
};
121121
// if we are in the UI thread, make sure we use progress monitor
122122
// that spins event loop to allow processing of pending asyncExecs
@@ -137,9 +137,13 @@ public synchronized final void run(IProgressMonitor monitor)
137137
interruptedException.initCause(e);
138138
throw interruptedException;
139139
}
140-
// Re-throw the InvocationTargetException, if any occurred
141-
if (iteHolder[0] != null) {
142-
throw iteHolder[0];
140+
141+
// Re-throw any exceptions caught while running the IWorkspaceRunnable
142+
if (rethrownInvocationTargetException.get() != null) {
143+
throw rethrownInvocationTargetException.get();
144+
}
145+
if (rethrownInterruptedException.get() != null) {
146+
throw rethrownInterruptedException.get();
143147
}
144148
}
145149
@Override

0 commit comments

Comments
 (0)