Project: Eclipse_Platform_UI
Bug 355210 EHandlerService's canExecute(*) should not propagate exceptions upwards if an error occurs during enablement evaluation
Reported: 2011-08-19 08:28:51 | Status: verified fixed

In 3.x, we have code like this in the Command class: try { return handler.isEnabled(); } catch (Exception e) { if (DEBUG_HANDLERS) { // since this has the ability to generate megs of logs, only // provide information if tracing Tracing.printTrace("HANDLERS", "Handler " + handler + " for " //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ + id + " threw unexpected exception"); //$NON-NLS-1$ e.printStackTrace(System.out); } } In 4.x, we don't have this protection in HandlerServiceImpl. If the handler's @CanExecute method has problems, an InjectionException ends up being thrown up to the caller of canExecute(*). We should instead return 'false' and then a) log the error or b) only log the error if we have tracing on (like in 3.x above). The absence of this exception protection causes problems when we're trying to evaluate the enablement and visibility of multiple contribution items as one exception will completely shutdown the evaluation of the other contribution items. What do you think, Paul? org.eclipse.e4.core.di.InjectionException: java.lang.NullPointerException at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:63) at org.eclipse.e4.core.internal.di.InjectorImpl.invokeUsingClass(InjectorImpl.java:228) at org.eclipse.e4.core.internal.di.InjectorImpl.invoke(InjectorImpl.java:209) at org.eclipse.e4.core.contexts.ContextInjectionFactory.invoke(ContextInjectionFactory.java:123) at org.eclipse.e4.core.commands.internal.HandlerServiceImpl.canExecute(HandlerServiceImpl.java:102) at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.updateElementVisibility(MenuManagerRendererFilter.java:344) at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.showMenu(MenuManagerRendererFilter.java:271) at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.handleShow(MenuManagerRendererFilter.java:225) at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.safeHandleEvent(MenuManagerRendererFilter.java:207) at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.access$1(MenuManagerRendererFilter.java:143) at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter$SafeWrapper.run(MenuManagerRendererFilter.java:130) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) at org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRendererFilter.handleEvent(MenuManagerRendererFilter.java:140) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) at org.eclipse.swt.widgets.Display.filterEvent(Display.java:1262) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1052) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1077) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1058) at org.eclipse.swt.widgets.Control.WM_INITMENUPOPUP(Control.java:4881) at org.eclipse.swt.widgets.Control.windowProc(Control.java:4557) at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:341) at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1610) at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2069) at org.eclipse.swt.widgets.Display.windowProc(Display.java:4972) at org.eclipse.swt.internal.win32.OS.TrackPopupMenu(Native Method) at org.eclipse.swt.widgets.Menu._setVisible(Menu.java:256) at org.eclipse.swt.widgets.Display.runPopups(Display.java:4206) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3748) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:969) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:885) at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:90) at org.eclipse.ui.internal.Workbench$3.run(Workbench.java:539) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:519) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149) at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123) at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:618) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577) at org.eclipse.equinox.launcher.Main.run(Main.java:1410) at org.eclipse.equinox.launcher.Main.main(Main.java:1386) Caused by: java.lang.NullPointerException at org.eclipse.emf.facet.widgets.nattable.internal.handlers.RemoveLineHandler.isEnabled(RemoveLineHandler.java:52) at org.eclipse.ui.internal.handlers.HandlerProxy.isEnabled(HandlerProxy.java:320) at org.eclipse.ui.internal.handlers.E4HandlerProxy.canExecute(E4HandlerProxy.java:53) at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:618) at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:56) ... 49 more

Files changed in fix:
bundles/org.eclipse.e4.core.commands/src/org/eclipse/e4/core/commands/internal/HandlerServiceImpl.java