From eae8d35fe8a240e8e8b8a220bcdfc3ddc67a4187 Mon Sep 17 00:00:00 2001 From: fedejeanne Date: Fri, 10 Nov 2023 14:11:23 +0100 Subject: [PATCH] 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 https://github.com/eclipse-platform/eclipse.platform.ui/pull/1259 --- .../ui/actions/WorkspaceModifyOperation.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/bundles/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/WorkspaceModifyOperation.java b/bundles/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/WorkspaceModifyOperation.java index 8a15723540c..49ed04cbb11 100644 --- a/bundles/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/WorkspaceModifyOperation.java +++ b/bundles/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/WorkspaceModifyOperation.java @@ -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; @@ -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 rethrownInvocationTargetException = new AtomicReference<>(); + AtomicReference 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 @@ -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